diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml index 464c6551..fdf759f0 100644 --- a/.github/workflows/pull-request.yml +++ b/.github/workflows/pull-request.yml @@ -20,7 +20,7 @@ jobs: - name: Run codespell uses: codespell-project/actions-codespell@master with: - skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server + skip: ./ArduinoCore-API,./libraries/ESP8266SdFat,./libraries/Adafruit_TinyUSB_Arduino,./libraries/LittleFS/lib,./tools/pyserial,./pico-sdk,./.github,./docs/i2s.rst,./cores/rp2040/api,./libraries/FreeRTOS,./tools/libbearssl/bearssl,./include,./libraries/WiFi/examples/BearSSL_Server,./ota/uzlib ignore_words_list: ser,dout # Consistent style diff --git a/.gitignore b/.gitignore index c6aec372..bc0a2616 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ .DS_Store system tools/dist -tools/libpico/build +docs/_build +ota/build +tools/libpico/build \ No newline at end of file diff --git a/.gitmodules b/.gitmodules index 53142aca..bcf48eeb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,3 +31,6 @@ [submodule "tools/libbearssl/bearssl"] path = tools/libbearssl/bearssl url = https://github.com/earlephilhower/bearssl-esp8266.git +[submodule "ota/uzlib"] + path = ota/uzlib + url = https://github.com/pfalcon/uzlib.git diff --git a/README.md b/README.md index 6d159ee1..df61ef52 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,8 @@ The installed tools include a version of OpenOCD (in the pqt-openocd directory) # Features * Adafruit TinyUSB Arduino (USB mouse, keyboard, flash drive, generic HID, CDC Serial, MIDI, WebUSB, others) * Generic Arduino USB Serial, Keyboard, and Mouse emulation +* WiFi (Pico W) +* Over-the-Air (OTA) upgrades * Filesystems (LittleFS and SD/SDFS) * Multicore support (setup1() and loop1()) * FreeRTOS SMP support @@ -184,6 +186,8 @@ If you want to contribute or have bugfixes, drop me a note at sizeof(obuf)) { + while ((size_t)src.available() > sizeof(obuf)) { src.read(obuf, sizeof(obuf)); sentLen = write(obuf, sizeof(obuf)); doneLen = doneLen + sentLen; diff --git a/cores/rp2040/RP2040Support.h b/cores/rp2040/RP2040Support.h index 05663725..465830cd 100644 --- a/cores/rp2040/RP2040Support.h +++ b/cores/rp2040/RP2040Support.h @@ -21,7 +21,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -311,6 +313,22 @@ public: multicore_launch_core1(main1); } + void reboot() { + watchdog_reboot(0, 0, 100); + } + + inline void restart() { + reboot(); + } + + const char *getChipID() { + static char id[PICO_UNIQUE_BOARD_ID_SIZE_BYTES + 1] = { 0 }; + if (!id[0]) { + pico_get_unique_board_id_string(id, sizeof(id)); + } + return id; + } + // Multicore comms FIFO _MFIFO fifo; diff --git a/cores/rp2040/StreamString.h b/cores/rp2040/StreamString.h new file mode 100644 index 00000000..39c5a232 --- /dev/null +++ b/cores/rp2040/StreamString.h @@ -0,0 +1,247 @@ +/** + StreamString.h + + Copyright (c) 2020 D. Gauchard. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef __STREAMSTRING_H +#define __STREAMSTRING_H + +#include +#include +#include "Stream.h" +#include "api/String.h" + +/////////////////////////////////////////////////////////////// +// S2Stream points to a String and makes it a Stream +// (it is also the helper for StreamString) + +class S2Stream: public Stream { +public: + S2Stream(String& string, int peekPointer = -1) : string(&string), peekPointer(peekPointer) { } + + S2Stream(String* string, int peekPointer = -1) : string(string), peekPointer(peekPointer) { } + + virtual int available() override { + return string->length(); + } + + virtual int availableForWrite() override { + return std::numeric_limits::max(); + } + + virtual int read() override { + if (peekPointer < 0) { + // consume chars + if (string->length()) { + char c = string->charAt(0); + string->remove(0, 1); + return c; + } + } else if (peekPointer < (int)string->length()) { + // return pointed and move pointer + return string->charAt(peekPointer++); + } + + // everything is read + return -1; + } + + virtual size_t write(uint8_t data) override { + return string->concat((char)data); + } + + // virtual int read(uint8_t* buffer, size_t len) override + // { + // if (peekPointer < 0) + // { + // // string will be consumed + // size_t l = std::min(len, (size_t)string->length()); + // memcpy(buffer, string->c_str(), l); + // string->remove(0, l); + // return l; + // } + // + // if (peekPointer >= (int)string->length()) + // { + // return 0; + // } + // + // // only the pointer is moved + // size_t l = std::min(len, (size_t)(string->length() - peekPointer)); + // memcpy(buffer, string->c_str() + peekPointer, l); + // peekPointer += l; + // return l; + // } + + virtual size_t write(const uint8_t* buffer, size_t len) override { + return string->concat((const char*)buffer, len) ? len : 0; + } + + virtual int peek() override { + if (peekPointer < 0) { + if (string->length()) { + return string->charAt(0); + } + } else if (peekPointer < (int)string->length()) { + return string->charAt(peekPointer); + } + + return -1; + } + + virtual void flush() override { + // nothing to do + } + +#if 0 + virtual bool inputCanTimeout() override { + return false; + } + + virtual bool outputCanTimeout() override { + return false; + } + + //// Stream's peekBufferAPI + + virtual bool hasPeekBufferAPI() const override { + return true; + } + + virtual size_t peekAvailable() { + if (peekPointer < 0) { + return string->length(); + } + return string->length() - peekPointer; + } + + virtual const char* peekBuffer() override { + if (peekPointer < 0) { + return string->c_str(); + } + if (peekPointer < (int)string->length()) { + return string->c_str() + peekPointer; + } + return nullptr; + } + + virtual void peekConsume(size_t consume) override { + if (peekPointer < 0) { + // string is really consumed + string->remove(0, consume); + } else { + // only the pointer is moved + peekPointer = std::min((size_t)string->length(), peekPointer + consume); + } + } + + virtual ssize_t streamRemaining() override { + return peekPointer < 0 ? string->length() : string->length() - peekPointer; + } + + // calling setConsume() will consume bytes as the stream is read + // (enabled by default) + void setConsume() { + peekPointer = -1; + } +#endif + // Reading this stream will mark the string as read without consuming + // (not enabled by default) + // Calling resetPointer() resets the read state and allows rereading. + void resetPointer(int pointer = 0) { + peekPointer = pointer; + } + +protected: + String* string; + int peekPointer; // -1:String is consumed / >=0:resettable pointer +}; + +// StreamString is a S2Stream holding the String + +class StreamString: public String, public S2Stream { +protected: + void resetpp() { + if (peekPointer > 0) { + peekPointer = 0; + } + } + +public: + StreamString(StreamString&& bro) : String(bro), S2Stream(this) { } + StreamString(const StreamString& bro) : String(bro), S2Stream(this) { } + + // duplicate String constructors and operator=: + + StreamString(const char* text = nullptr) : String(text), S2Stream(this) { } + StreamString(const String& string) : String(string), S2Stream(this) { } + StreamString(const __FlashStringHelper* str) : String(str), S2Stream(this) { } + StreamString(String&& string) : String(string), S2Stream(this) { } + + explicit StreamString(char c) : String(c), S2Stream(this) { } + explicit StreamString(unsigned char c, unsigned char base = 10) : + String(c, base), S2Stream(this) { + } + explicit StreamString(int i, unsigned char base = 10) : String(i, base), S2Stream(this) { } + explicit StreamString(unsigned int i, unsigned char base = 10) : String(i, base), S2Stream(this) { + } + explicit StreamString(long l, unsigned char base = 10) : String(l, base), S2Stream(this) { } + explicit StreamString(unsigned long l, unsigned char base = 10) : + String(l, base), S2Stream(this) { + } + explicit StreamString(float f, unsigned char decimalPlaces = 2) : + String(f, decimalPlaces), S2Stream(this) { + } + explicit StreamString(double d, unsigned char decimalPlaces = 2) : + String(d, decimalPlaces), S2Stream(this) { + } + + StreamString& operator=(const StreamString& rhs) { + String::operator=(rhs); + resetpp(); + return *this; + } + + StreamString& operator=(const String& rhs) { + String::operator=(rhs); + resetpp(); + return *this; + } + + StreamString& operator=(const char* cstr) { + String::operator=(cstr); + resetpp(); + return *this; + } + + StreamString& operator=(const __FlashStringHelper* str) { + String::operator=(str); + resetpp(); + return *this; + } + + StreamString& operator=(String&& rval) { + String::operator=(rval); + resetpp(); + return *this; + } +}; + +#endif // __STREAMSTRING_H diff --git a/docs/index.rst b/docs/index.rst index e98a4026..cf191af2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -50,6 +50,8 @@ For the latest version, always check https://github.com/earlephilhower/arduino-p WiFiClientSecure (TLS/SSL/HTTPS) WiFiServerSecure (TLS/SSL/HTTPS) + Over-the-Air (OTA) Updates + Ported/Optimized Libraries Using Pico-SDK diff --git a/docs/ota.rst b/docs/ota.rst new file mode 100755 index 00000000..d8305ab7 --- /dev/null +++ b/docs/ota.rst @@ -0,0 +1,239 @@ +OTA Updates +=========== + + +Introduction +------------ + +OTA (Over the Air) update is the process of uploading firmware to a Pico using a Wi-Fi, Ethernet, or other connection rather than a serial port. This is especially useful for WiFi enabled Picos, like the Pico W, because it lets systems be updated remotely, without needing physical access. + +OTA may be done using: + +- `Arduino IDE <#arduino-ide>`__ +- `Web Browser <#web-browser>`__ - Coming soon +- `HTTP Server <#http-server>`__ - Coming soon + +The Arduino IDE option is intended primarily for the software development phase. The other two options would be more useful after deployment, to provide the module with application updates either manually with a web browser, or automatically using an HTTP server. + +In any case, the first firmware upload has to be done over a serial port. If the OTA routines are correctly implemented in the sketch, then all subsequent uploads may be done over the air. + +By default, there is no imposed security for the OTA process. It is up to the developer to ensure that updates are allowed only from legitimate / trusted sources. Once the update is complete, the module restarts, and the new code is executed. The developer should ensure that the application running on the module is shut down and restarted in a safe manner. Chapters below provide additional information regarding security and safety of OTA updates. + +OTA Requirements +~~~~~~~~~~~~~~~~ + +OTA requires a LittleFS partition to store firmware upgrade files. Make sure that you configure the sketch with a filesystem large enough to handle whatever size firmware binary you expect. Updates may be compressed, minimizing the total space needed. + +Power Fail Safety +~~~~~~~~~~~~~~~~~ + +The update commands are all stored in flash, so a power cycle during update (except if the OTA bootloader is being changed) should not brick the device because when power is restored the OTA bootloader will begin the process from scratch once again. + + +Security Disclaimer +~~~~~~~~~~~~~~~~~~~ + +No guarantees as to the level of security provided for your application by the following methods is implied. Please refer to the GNU LGPL license associated for this project for full disclaimers. If you do find security weaknesses, please don't hesitate to contact the maintainers or supply pull requests with fixes. The MD5 verification and password protection schemes are already known to supply a very weak level of security. + +Basic Security +~~~~~~~~~~~~~~ + +The module has to be exposed wirelessly to get it updated with a new sketch. That poses a risk of the module being violently hacked and programmed with some other code. To reduce the likelihood of being hacked, consider protecting your uploads with a password, selecting certain OTA port, etc. + +Check functionality provided with the `ArduinoOTA `__ library that may improve security: + +.. code:: cpp + + void setPort(uint16_t port); + void setHostname(const char* hostname); + void setPassword(const char* password); + +Certain basic protection is already built in and does not require any additional coding by the developer. `ArduinoOTA `__ and espota.py use `Digest-MD5 `__ to authenticate uploads. Integrity of transferred data is verified on the ESP side using `MD5 `__ checksum. + +Make your own risk analysis and, depending on the application, decide what library functions to implement. If required, consider implementation of other means of protection from being hacked, like exposing modules for uploads only according to a specific schedule, triggering OTA only when the user presses a dedicated “Update” button wired to the ESP, etc. + +Advanced Security - Signed Updates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +While the above password-based security will dissuade casual hacking attempts, it is not highly secure. For applications where a higher level of security is needed, cryptographically signed OTA updates can be required. This uses SHA256 hashing in place of MD5 (which is known to be cryptographically broken) and RSA-2048 bit level public-key encryption to guarantee that only the holder of a cryptographic private key can produce signed updates accepted by the OTA update mechanisms. + +Signed updates are updates whose compiled binaries are signed with a private key (held by the developer) and verified with a public key (stored in the application and available for all to see). The signing process computes a hash of the binary code, encrypts the hash with the developer's private key, and appends this encrypted hash (also called a signature) to the binary that is uploaded (via OTA, web, or HTTP server). If the code is modified or replaced in any way by anyone except the holder of the developer's private key, the signature will not match and the ESP8266 will reject the upload. + +Cryptographic signing only protects against tampering with binaries delivered via OTA. If someone has physical access, they will always be able to flash the device over the serial port. Signing also does not encrypt anything but the hash (so that it can't be modified), so this does not protect code inside the device: if a user has physical access they can read out your program. + +**Securing your private key is paramount. The same private/public key pair that was used with the original upload must also be used to sign later binaries. Loss of the private key associated with a binary means that you will not be able to OTA-update any of your devices in the field. Alternatively, if someone else copies the private key, then they will be able to use it to sign binaries which will be accepted by the Pico.** + +Signed Binary Format +^^^^^^^^^^^^^^^^^^^^ + +The format of a signed binary is compatible with the standard binary format, and can be uploaded to a non-signed Pico via serial or OTA without any conditions. Note, however, that once an unsigned OTA app is overwritten by this signed version, further updates will require signing. + +As shown below, the signed hash is appended to the unsigned binary, followed by the total length of the signed hash (i.e., if the signed hash was 64 bytes, then this uint32 data segment will contain 64). This format allows for extensibility (such as adding a CA-based validation scheme allowing multiple signing keys all based on a trust anchor). Pull requests are always welcome. (currently it uses SHA256 with RSASSA-PKCS1-V1_5-SIGN signature scheme from RSA PKCS #1 v1.5) + +.. code:: bash + + NORMAL-BINARY + +Signed Binary Prerequisites +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +OpenSSL is required to run the standard signing steps, and should be available on any UNIX-like or Windows system. As usual, the latest stable version of OpenSSL is recommended. + +Signing requires the generation of an RSA-2048 key (other bit lengths are supported as well, but 2048 is a good selection today) using any appropriate tool. The following shell commands will generate a new public/private key pair. Run them in the sketch directory: + +.. code:: bash + + openssl genrsa -out private.key 2048 + openssl rsa -in private.key -outform PEM -pubout -out public.key + +Automatic Signing +^^^^^^^^^^^^^^^^^ + +The simplest way of implementing signing is to use the automatic mode, which presently is only possible on Linux and Mac due to some of the tools not being available for Windows. This mode uses the IDE to configure the source code to enable sigining verification with a given public key, and signs binaries as part of the standard build process using a given public key. + +To enable this mode, just include `private.key` and `public.key` in the sketch `.ino` directory. The IDE will call a helper script (`tools/signing.py`) before the build begins to create a header to enable key validation using the given public key, and to actually do the signing after the build process, generating a `sketch.bin.signed` file. When OTA is enabled (ArduinoOTA, Web, or HTTP), the binary will automatically only accept signed updates. + +When the signing process starts, the message: + +.. code:: bash + + Enabling binary signing + +will appear in the IDE window before a compile is launched. At the completion of the build, the signed binary file well be displayed in the IDE build window as: + +.. code:: bash + + Signed binary: /full/path/to/sketch.bin.signed + +If you receive either of the following messages in the IDE window, the signing was not completed and you will need to verify the `public.key` and `private.key`: + +.. code:: bash + + Not enabling binary signing + ... or ... + Not signing the generated binary + +Manual Signing of Binaries +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Users may also manually sign executables and require the OTA process to verify their signature. In the main code, before enabling any update methods, add the following declarations and function call: + +.. code:: cpp + + + BearSSL::PublicKey signPubKey( ... key contents ... ); + BearSSL::HashSHA256 hash; + BearSSL::SigningVerifier sign( &signPubKey ); + ... + + Update.installSignature( &hash, &sign ); + +The above snippet creates a BearSSL public key and a SHA256 hash verifier, and tells the Update object to use them to validate any updates it receives from any method. + +Compile the sketch normally and, once a `.bin` file is available, sign it using the signer script: + +.. code:: bash + + /tools/signing.py --mode sign --privatekey --bin --out + +Compression +----------- + +The eboot bootloader incorporates a GZIP decompressor, built for very low code requirements. For applications, this optional decompression is completely transparent. For uploading compressed filesystems, the application must be built with `ATOMIC_FS_UPDATE` defined because, otherwise, eboot will not be involved in writing the filesystem. + +No changes to the application are required. The `Updater` class and `eboot` bootloader (which performs actual application overwriting on update) automatically search for the `gzip` header in the uploaded binary, and if found, handle it. + +Compress an application `.bin` file or filesystem package using any `gzip` available, at any desired compression level (`gzip -9` is recommended because it provides the maximum compression and uncompresses as fast as any other compressino level). For example: + +.. code:: bash + + gzip -9 sketch.bin # Maximum compression, output sketch.bin.gz + + +If signing is desired, sign the gzip compressed file *after* compression. + +.. code:: bash + + gzip -9 sketch.bin + /tools/signing.py --mode sign --privatekey --bin sketch.bin.gz --out sketch.bin.gz.signed + +Safety +~~~~~~ + +The OTA process consumes some of the ESP’s resources and bandwidth during upload. Then, the module is restarted and a new sketch executed. Analyse and test how this affects the functionality of the existing and new sketches. + +If the ESP is in a remote location and controlling some equipment, you should devote additional attention to what happens if operation of this equipment is suddenly interrupted by the update process. Therefore, decide how to put this equipment into a safe state before starting the update. For instance, your module may be controlling a garden watering system in a sequence. If this sequence is not properly shut down and a water valve is left open, the garden may be flooded. + +The following functions are provided with the `ArduinoOTA `__ library and intended to handle functionality of your application during specific stages of OTA, or on an OTA error: + +.. code:: cpp + + void onStart(OTA_CALLBACK(fn)); + void onEnd(OTA_CALLBACK(fn)); + void onProgress(OTA_CALLBACK_PROGRESS(fn)); + void onError(OTA_CALLBACK_ERROR (fn)); + +Uploading from the Arduino IDE +------------------------------ + +Uploading modules wirelessly from Arduino IDE is intended for the following typical scenarios: + +- During firmware development as a quicker alternative to loading over a serial port, + +- For updating a small number of modules, + +- Only if modules are accessible on the same network as the computer with the Arduino IDE. + +- For all IDE uploads,m the Pico W and the computer must be connected to the same network. + +To upload wirelessly from the IDE: + +1. Build a sketch starts ``WiFi`` and includes the appropriare calls to ``ArduinoOTA`` (see the examples for reference). These include the ``ArduinoOTA.begin()`` call in ``setup()`` and periodically calling ``ArduinoOTA.handle();`` from the ``loop()`` + +2. Upload using standard USB connection the first time. + +3. The ``Tools->Port`` should now list ``pico-######`` under the ``Network Ports``. Select it (you won't be able to use the serial monitor, of course). + +4. Try another upload. It should display the OTA process in place of the serial port upload. + +Password Protection +------------------- + +Protecting your OTA uploads with password is really straightforward. All you need to do, is to include the following statement in your code: + +.. code:: cpp + + ArduinoOTA.setPassword((const char *)"123"); + +Where ``123`` is a sample password that you should replace with your own. + +Before implementing it in your sketch, it is a good idea to check how it works using *BasicOTA.ino* sketch available under *File > Examples > ArduinoOTA*. Go ahead, open *BasicOTA.ino*, uncomment the above statement that is already there, and upload the sketch. To make troubleshooting easier, do not modify example sketch besides what is absolutely required. This is including original simple ``123`` OTA password. Then attempt to upload sketch again (using OTA). After compilation is complete, once upload is about to begin, you should see prompt for password. + +Enter the password and upload should be initiated as usual with the only difference being ``Authenticating...OK`` message visible in upload log. + +You will not be prompted for a reentering the same password next time. Arduino IDE will remember it for you. You will see prompt for password only after reopening IDE, or if you change it in your sketch, upload the sketch and then try to upload it again. + +Please note, it is possible to reveal password entered previously in Arduino IDE, if IDE has not been closed since last upload. This can be done by enabling *Show verbose output during: upload* in *File > Preferences* and attempting to upload the module. + +Stream Interface +---------------- + +The Stream Interface is the base for all other update modes like OTA, HTTP Server / client. Given a Stream-class variable `streamVar` providing `byteCount` bytes of firmware, it can store the firmware as follows: + +.. code:: cpp + + Update.begin(firmwareLengthInBytes); + Update.writeStream(streamVar); + Update.end(); + +OTA Bootloader and Memory Map +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A firmware file is uploaded via any method (Ethernet, WiFi, serial ZModem, etc.) and stored on the LittleFS filesystem as a normal file. The Updater class (or the underlying PicoOTA) will make a special "OTA command" file on the filesystem, which will be read by the OTA bootloader. On a reboot, this OTA bootloader will check for an upgrade file, verify its contents, and then perform the requested update and reboot. If no upgrade file is present, the OTA bootloader simply jumps to the main sketch. + +The ROM layout consists of: + +... code: + + [boot2.S] [OTA Bootloader] [0-pad] [OTA partition table] [Main sketch] [LittleFS filesystem] [EEPROM] + diff --git a/docs/rp2040.rst b/docs/rp2040.rst index dcf7ae1a..5d39dc18 100644 --- a/docs/rp2040.rst +++ b/docs/rp2040.rst @@ -33,6 +33,10 @@ values returned may not meet the most stringent random tests. **If your application needs absolute bulletproof random numbers, consider using dedicated external hardware.** +void reboot() +~~~~~~~~~~~~~ +Forces a hardware reboot of the Pico. + Memory Information ------------------ diff --git a/include/pico_base/pico/ota_command.h b/include/pico_base/pico/ota_command.h new file mode 100644 index 00000000..e0b4d158 --- /dev/null +++ b/include/pico_base/pico/ota_command.h @@ -0,0 +1,50 @@ +/* + ota_command.h - OTA stub that copies from LittleFS to flash + Copyright (c) 2022 Earle F. Philhower, III. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include + +#define _OTA_WRITE 1 +#define _OTA_VERIFY 1 + +typedef struct { + uint32_t command; + union { + struct { + char filename[64]; + uint32_t fileOffset; + uint32_t fileLength; + uint32_t flashAddress; // Normally XIP_BASE + } write; + }; +} commandEntry; + +// Must fit within 4K page +typedef struct { + uint8_t sign[8]; // "Pico OTA" + + // List of operations + uint32_t count; + commandEntry cmd[8]; + + uint32_t crc32; // CRC32 over just the contents of this struct, up until just before this value +} OTACmdPage; + +#define _OTA_COMMAND_FILE "otacommand.bin" diff --git a/keywords.txt b/keywords.txt index 93680db3..d6174707 100644 --- a/keywords.txt +++ b/keywords.txt @@ -23,6 +23,8 @@ pop KEYWORD2 pop_nb KEYWORD2 rp2040 KEYWORD2 +reboot KEYWORD2 +restart KEYWORD2 RP2040 KEYWORD2 usToPIOCycles KEYWORD2 f_cpu KEYWORD2 diff --git a/lib/memmap_default.ld b/lib/memmap_default.ld index 04ecd042..90dde3ce 100644 --- a/lib/memmap_default.ld +++ b/lib/memmap_default.ld @@ -55,6 +55,28 @@ SECTIONS ASSERT(__boot2_end__ - __boot2_start__ == 256, "ERROR: Pico second stage bootloader must be 256 bytes in size") + .ota : { + /* Start image with OTA */ + KEEP (*(.OTA)) + /* Align to the last 16-bytes of the OTA region */ + /* If anyone has a better way of doing this, please submit a PR! */ + /* . = __flash_binary_start + 0x2ff0; + LONG(__FS_START__) + LONG(__FS_END__) + LONG(__EEPROM_START__) + LONG(__FLASH_LENGTH__)*/ + } > FLASH + + .partition : { + /* Align to the last 16-bytes of the OTA region */ + /* If anyone has a better way of doing this, please submit a PR! */ + . = __flash_binary_start + 0x2ff0; + LONG(__FS_START__) + LONG(__FS_END__) + LONG(__EEPROM_START__) + LONG(__FLASH_LENGTH__) + } > FLASH + /* The second stage will always enter the image at the start of .text. The debugger will use the ELF entry point, which is the _entry_point symbol if present, otherwise defaults to start of .text. diff --git a/lib/ota.o b/lib/ota.o new file mode 100644 index 00000000..0b330e25 Binary files /dev/null and b/lib/ota.o differ diff --git a/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino new file mode 100644 index 00000000..3279bf7b --- /dev/null +++ b/libraries/ArduinoOTA/examples/BasicOTA/BasicOTA.ino @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +#ifndef STASSID +#define STASSID "your-ssid" +#define STAPSK "your-password" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; + +void setup() { + Serial.begin(115200); + Serial.println("Booting"); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + while (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.println("Connection Failed! Rebooting..."); + delay(5000); + rp2040.restart(); + } + + // Port defaults to 8266 + // ArduinoOTA.setPort(8266); + + // Hostname defaults to esp8266-[ChipID] + // ArduinoOTA.setHostname("myesp8266"); + + // No authentication by default + // ArduinoOTA.setPassword("admin"); + + // Password can be set with it's md5 value as well + // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 + // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); + + ArduinoOTA.onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) { + type = "sketch"; + } else { // U_FS + type = "filesystem"; + } + + // NOTE: if updating FS this would be the place to unmount FS using FS.end() + Serial.println("Start updating " + type); + }); + ArduinoOTA.onEnd([]() { + Serial.println("\nEnd"); + }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("Progress: %u%%\r", (progress / (total / 100))); + }); + ArduinoOTA.onError([](ota_error_t error) { + Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) { + Serial.println("Auth Failed"); + } else if (error == OTA_BEGIN_ERROR) { + Serial.println("Begin Failed"); + } else if (error == OTA_CONNECT_ERROR) { + Serial.println("Connect Failed"); + } else if (error == OTA_RECEIVE_ERROR) { + Serial.println("Receive Failed"); + } else if (error == OTA_END_ERROR) { + Serial.println("End Failed"); + } + }); + ArduinoOTA.begin(); + Serial.println("Ready"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + ArduinoOTA.handle(); +} diff --git a/libraries/ArduinoOTA/examples/OTALeds/OTALeds.ino b/libraries/ArduinoOTA/examples/OTALeds/OTALeds.ino new file mode 100644 index 00000000..7e9dcfd8 --- /dev/null +++ b/libraries/ArduinoOTA/examples/OTALeds/OTALeds.ino @@ -0,0 +1,74 @@ +#include +#include +#include +#include + +#ifndef STASSID +#define STASSID "your-ssid" +#define STAPSK "your-password" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; +const char* host = "OTA-LEDS"; + +int led_pin = 13; +#define N_DIMMERS 3 +int dimmer_pin[] = { 14, 5, 15 }; + +void setup() { + Serial.begin(115200); + + /* switch on led */ + pinMode(led_pin, OUTPUT); + digitalWrite(led_pin, LOW); + + Serial.println("Booting"); + WiFi.mode(WIFI_STA); + + WiFi.begin(ssid, password); + + while (WiFi.waitForConnectResult() != WL_CONNECTED) { + WiFi.begin(ssid, password); + Serial.println("Retrying connection..."); + } + /* switch off led */ + digitalWrite(led_pin, HIGH); + + /* configure dimmers, and OTA server events */ + analogWriteRange(1000); + analogWrite(led_pin, 990); + + for (int i = 0; i < N_DIMMERS; i++) { + pinMode(dimmer_pin[i], OUTPUT); + analogWrite(dimmer_pin[i], 50); + } + + ArduinoOTA.setHostname(host); + ArduinoOTA.onStart([]() { // switch off all the PWMs during upgrade + for (int i = 0; i < N_DIMMERS; i++) { + analogWrite(dimmer_pin[i], 0); + } + analogWrite(led_pin, 0); + }); + + ArduinoOTA.onEnd([]() { // do a fancy thing with our board led at end + for (int i = 0; i < 30; i++) { + analogWrite(led_pin, (i * 100) % 1001); + delay(50); + } + }); + + ArduinoOTA.onError([](ota_error_t error) { + (void)error; + rp2040.restart(); + }); + + /* setup the OTA server */ + ArduinoOTA.begin(); + Serial.println("Ready"); +} + +void loop() { + ArduinoOTA.handle(); +} diff --git a/libraries/ArduinoOTA/examples/SignedOTA-blink/SignedOTA-blink.ino b/libraries/ArduinoOTA/examples/SignedOTA-blink/SignedOTA-blink.ino new file mode 100644 index 00000000..da45242f --- /dev/null +++ b/libraries/ArduinoOTA/examples/SignedOTA-blink/SignedOTA-blink.ino @@ -0,0 +1,19 @@ +// To be used with SignedOTA. The IDE will sign the binary +// automatically and upload over WiFi + +// Released to the public domain, Earle Philhower, 2022 + +#include + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); + srand(123); +} + +void loop() { + int del = rand() % 100; + digitalWrite(LED_BUILTIN, HIGH); + delay(del * 10); + digitalWrite(LED_BUILTIN, LOW); + delay(del * 10); +} diff --git a/libraries/ArduinoOTA/examples/SignedOTA-blink/private.key b/libraries/ArduinoOTA/examples/SignedOTA-blink/private.key new file mode 100644 index 00000000..09e3bc12 --- /dev/null +++ b/libraries/ArduinoOTA/examples/SignedOTA-blink/private.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAu1Pt7yEk/xI+6cozLj5Bu4xV8gXDXcHS0rSJFfl4wBTk4UXp +aJRaLfR1k0juEEa5LBRZaoA0iLj2e6kfCibONx0VVoWmeqN2HBc3zkA1eqCksI0Q +Uudzto4KhKHp0odiZ2zo6c/2Tn1zqD/m3OLoSjVTbsJmGuwx8RGMBXozpg/uL0hH +flihX+HND4Xfw92QXv7SaPBhgvM9xyRxn0/w3J2nNjtuPuVN5vcQkd8ncMexVfy9 +AWp+HSA5AT5N8CJ/EeIsdDMY1US28bUePzj1WIo75bZHKZNFw/iXe2xoPpm74qri +MNSlW2craFP2K3KYnI28vJeUU6t9I6LS9zt2zQIDAQABAoIBAE5GpuDKb8Qp4qIc +fMBxAVSWMn+cSuONj0O+bp4BDaTt1ioP5ZVukDQtt0ehLOEePFgf9LEc+1a6Ozy3 +EaJTTs4W2Ai8djE+xqa8SPRlPjOMluSzPUP3NRHuTpTXd3YiXksrZjP1U02+/Cos +8ZIROtFvcPqSPso3MjMyitjrFFPqEtf1P+UiamjDrMSM72YX4W55kOkiCWCnAOmw +mGTlXOIqDSTBb1lloKWJfpB3RdnNo2izkU1HMBn7hVi433NUBA22o+RZhDFSZdD4 +3kbkUqXd4p+vc/sh6muJtWS/COSIPFkLzdEYpBdt3XQ4FhlsRtILJaPWXa4OPjR6 +ZoOwMB0CgYEA6OHfIofQiu4+HlTDN5YdyTmtYEYcrtbaQUxuQSEa2mshBphHP8uT +mYRVl2BzuprFmXZPz+FcjnPnfxqEehljvA3wMjA/PE+nQo9yyOC0N4ulXpkkqHdR +f+4KZVR7D+hesGe+57OQmvTqYZSHEt/ubjC9wZ90UFonLjsa4zibbrsCgYEAzexn +XDnThb3ffyBgvprP0IJjgMAEY0pXD++PKPQqPu9JMz68t7roYzkKFCFVOsaWpKxC +vX9mvYjTBjLpWh+ltIAN+EFz6seIbeSJ0RNybsAXYwT/mFWGHx2tMtlW6DgBu3UD +J2Yf76n0JaddBkfNMQI00Dl41+MU+AwwTB9fTBcCgYB2+f6Pm6d1cyYVROS/X1g0 +V9011FwPDwFOXwftCka31Ad5YQ71jsIHqk44GjTF3xCYyJMZ917cAGcCzr9jydjk +WJKgcXm9DEy9ep//9Jzdy+BepgrObrcajriM8E424FaP9VDY+yojoICl/cXMZM9h +SFGJvDcmXgiqW9PuxhrSxQKBgAMN2oqXoPd+1W3BQS4ShbqF9IvYTThbxebKmsj0 +thuw2NkVuR7Qetnd4rRhui3g/CL9GxBMb22oNdkFsEhR59dBfvOLpPh6dR+MIC8l +prDV0IL7c/8CZbbYbdUvPAa9rejl12IiNZ8MWj6kuNB7CCQN8FKWR6CMEaeMJrs6 +S+OJAoGAbehNOUwEzmUKkfxf+279kBkgabcQ3NTaeSx0QOnI9KWHFGLYLQk9cMSu +maQJ1TYpbIoP1njzJ4bI2tynhwEuSMEhh4afP6U5H10NJX4PqSd0Rqc1vSJYcszr +5mUWil8FfbCBZ8jod2NQ55KYMVY5CphCqaK/s2bw2pvIR3uqJGg= +-----END RSA PRIVATE KEY----- diff --git a/libraries/ArduinoOTA/examples/SignedOTA-blink/public.key b/libraries/ArduinoOTA/examples/SignedOTA-blink/public.key new file mode 100644 index 00000000..054e88b1 --- /dev/null +++ b/libraries/ArduinoOTA/examples/SignedOTA-blink/public.key @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1Pt7yEk/xI+6cozLj5B +u4xV8gXDXcHS0rSJFfl4wBTk4UXpaJRaLfR1k0juEEa5LBRZaoA0iLj2e6kfCibO +Nx0VVoWmeqN2HBc3zkA1eqCksI0QUudzto4KhKHp0odiZ2zo6c/2Tn1zqD/m3OLo +SjVTbsJmGuwx8RGMBXozpg/uL0hHflihX+HND4Xfw92QXv7SaPBhgvM9xyRxn0/w +3J2nNjtuPuVN5vcQkd8ncMexVfy9AWp+HSA5AT5N8CJ/EeIsdDMY1US28bUePzj1 +WIo75bZHKZNFw/iXe2xoPpm74qriMNSlW2craFP2K3KYnI28vJeUU6t9I6LS9zt2 +zQIDAQAB +-----END PUBLIC KEY----- diff --git a/libraries/ArduinoOTA/examples/SignedOTA/SignedOTA.ino b/libraries/ArduinoOTA/examples/SignedOTA/SignedOTA.ino new file mode 100644 index 00000000..6c354f46 --- /dev/null +++ b/libraries/ArduinoOTA/examples/SignedOTA/SignedOTA.ino @@ -0,0 +1,91 @@ +// Simple Signed OTA example +// Released to the public domain by Earle Philhower, Aug 2022 +// +// Note that the actual code of this is the same as the BasicOTA. No user +// code changes are needed, only the presence of public.key and private.key +// in the sketch directory. The core will automatically sign any binaries +// and include the necessary code to verify signatures. For more info +// check the documentation +// +// After uploading this sketch, try uploading the SignedOTA-Blink sketch +// All unsigned binaries, or binaries signed with a different private +// key will fail to upload. + + +#include +#include +#include +#include + +#ifndef STASSID +#define STASSID "your-ssid" +#define STAPSK "your-password" +#endif + +const char* ssid = STASSID; +const char* password = STAPSK; + +void setup() { + Serial.begin(115200); + Serial.println("Booting"); + WiFi.mode(WIFI_STA); + WiFi.begin(ssid, password); + while (WiFi.waitForConnectResult() != WL_CONNECTED) { + Serial.println("Connection Failed! Rebooting..."); + delay(5000); + rp2040.restart(); + } + + // Port defaults to 8266 + // ArduinoOTA.setPort(8266); + + // Hostname defaults to esp8266-[ChipID] + // ArduinoOTA.setHostname("myesp8266"); + + // No authentication by default + // ArduinoOTA.setPassword("admin"); + + // Password can be set with it's md5 value as well + // MD5(admin) = 21232f297a57a5a743894a0e4a801fc3 + // ArduinoOTA.setPasswordHash("21232f297a57a5a743894a0e4a801fc3"); + + ArduinoOTA.onStart([]() { + String type; + if (ArduinoOTA.getCommand() == U_FLASH) { + type = "sketch"; + } else { // U_FS + type = "filesystem"; + } + + // NOTE: if updating FS this would be the place to unmount FS using FS.end() + Serial.println("Start updating " + type); + }); + ArduinoOTA.onEnd([]() { + Serial.println("\nEnd"); + }); + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + Serial.printf("Progress: %u%%\r\n", (progress / (total / 100))); + }); + ArduinoOTA.onError([](ota_error_t error) { + Serial.printf("Error[%u]: ", error); + if (error == OTA_AUTH_ERROR) { + Serial.println("Auth Failed"); + } else if (error == OTA_BEGIN_ERROR) { + Serial.println("Begin Failed"); + } else if (error == OTA_CONNECT_ERROR) { + Serial.println("Connect Failed"); + } else if (error == OTA_RECEIVE_ERROR) { + Serial.println("Receive Failed"); + } else if (error == OTA_END_ERROR) { + Serial.println("End Failed"); + } + }); + ArduinoOTA.begin(); + Serial.println("Ready"); + Serial.print("IP address: "); + Serial.println(WiFi.localIP()); +} + +void loop() { + ArduinoOTA.handle(); +} diff --git a/libraries/ArduinoOTA/examples/SignedOTA/private.key b/libraries/ArduinoOTA/examples/SignedOTA/private.key new file mode 100644 index 00000000..09e3bc12 --- /dev/null +++ b/libraries/ArduinoOTA/examples/SignedOTA/private.key @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAu1Pt7yEk/xI+6cozLj5Bu4xV8gXDXcHS0rSJFfl4wBTk4UXp +aJRaLfR1k0juEEa5LBRZaoA0iLj2e6kfCibONx0VVoWmeqN2HBc3zkA1eqCksI0Q +Uudzto4KhKHp0odiZ2zo6c/2Tn1zqD/m3OLoSjVTbsJmGuwx8RGMBXozpg/uL0hH +flihX+HND4Xfw92QXv7SaPBhgvM9xyRxn0/w3J2nNjtuPuVN5vcQkd8ncMexVfy9 +AWp+HSA5AT5N8CJ/EeIsdDMY1US28bUePzj1WIo75bZHKZNFw/iXe2xoPpm74qri +MNSlW2craFP2K3KYnI28vJeUU6t9I6LS9zt2zQIDAQABAoIBAE5GpuDKb8Qp4qIc +fMBxAVSWMn+cSuONj0O+bp4BDaTt1ioP5ZVukDQtt0ehLOEePFgf9LEc+1a6Ozy3 +EaJTTs4W2Ai8djE+xqa8SPRlPjOMluSzPUP3NRHuTpTXd3YiXksrZjP1U02+/Cos +8ZIROtFvcPqSPso3MjMyitjrFFPqEtf1P+UiamjDrMSM72YX4W55kOkiCWCnAOmw +mGTlXOIqDSTBb1lloKWJfpB3RdnNo2izkU1HMBn7hVi433NUBA22o+RZhDFSZdD4 +3kbkUqXd4p+vc/sh6muJtWS/COSIPFkLzdEYpBdt3XQ4FhlsRtILJaPWXa4OPjR6 +ZoOwMB0CgYEA6OHfIofQiu4+HlTDN5YdyTmtYEYcrtbaQUxuQSEa2mshBphHP8uT +mYRVl2BzuprFmXZPz+FcjnPnfxqEehljvA3wMjA/PE+nQo9yyOC0N4ulXpkkqHdR +f+4KZVR7D+hesGe+57OQmvTqYZSHEt/ubjC9wZ90UFonLjsa4zibbrsCgYEAzexn +XDnThb3ffyBgvprP0IJjgMAEY0pXD++PKPQqPu9JMz68t7roYzkKFCFVOsaWpKxC +vX9mvYjTBjLpWh+ltIAN+EFz6seIbeSJ0RNybsAXYwT/mFWGHx2tMtlW6DgBu3UD +J2Yf76n0JaddBkfNMQI00Dl41+MU+AwwTB9fTBcCgYB2+f6Pm6d1cyYVROS/X1g0 +V9011FwPDwFOXwftCka31Ad5YQ71jsIHqk44GjTF3xCYyJMZ917cAGcCzr9jydjk +WJKgcXm9DEy9ep//9Jzdy+BepgrObrcajriM8E424FaP9VDY+yojoICl/cXMZM9h +SFGJvDcmXgiqW9PuxhrSxQKBgAMN2oqXoPd+1W3BQS4ShbqF9IvYTThbxebKmsj0 +thuw2NkVuR7Qetnd4rRhui3g/CL9GxBMb22oNdkFsEhR59dBfvOLpPh6dR+MIC8l +prDV0IL7c/8CZbbYbdUvPAa9rejl12IiNZ8MWj6kuNB7CCQN8FKWR6CMEaeMJrs6 +S+OJAoGAbehNOUwEzmUKkfxf+279kBkgabcQ3NTaeSx0QOnI9KWHFGLYLQk9cMSu +maQJ1TYpbIoP1njzJ4bI2tynhwEuSMEhh4afP6U5H10NJX4PqSd0Rqc1vSJYcszr +5mUWil8FfbCBZ8jod2NQ55KYMVY5CphCqaK/s2bw2pvIR3uqJGg= +-----END RSA PRIVATE KEY----- diff --git a/libraries/ArduinoOTA/examples/SignedOTA/public.key b/libraries/ArduinoOTA/examples/SignedOTA/public.key new file mode 100644 index 00000000..054e88b1 --- /dev/null +++ b/libraries/ArduinoOTA/examples/SignedOTA/public.key @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1Pt7yEk/xI+6cozLj5B +u4xV8gXDXcHS0rSJFfl4wBTk4UXpaJRaLfR1k0juEEa5LBRZaoA0iLj2e6kfCibO +Nx0VVoWmeqN2HBc3zkA1eqCksI0QUudzto4KhKHp0odiZ2zo6c/2Tn1zqD/m3OLo +SjVTbsJmGuwx8RGMBXozpg/uL0hHflihX+HND4Xfw92QXv7SaPBhgvM9xyRxn0/w +3J2nNjtuPuVN5vcQkd8ncMexVfy9AWp+HSA5AT5N8CJ/EeIsdDMY1US28bUePzj1 +WIo75bZHKZNFw/iXe2xoPpm74qriMNSlW2craFP2K3KYnI28vJeUU6t9I6LS9zt2 +zQIDAQAB +-----END PUBLIC KEY----- diff --git a/libraries/ArduinoOTA/keywords.txt b/libraries/ArduinoOTA/keywords.txt new file mode 100644 index 00000000..1c14d9e8 --- /dev/null +++ b/libraries/ArduinoOTA/keywords.txt @@ -0,0 +1,26 @@ +####################################### +# Syntax Coloring Map For Ultrasound +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +ArduinoOTA KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +setup KEYWORD2 +handle KEYWORD2 +onStart KEYWORD2 +onEnd KEYWORD2 +onError KEYWORD2 +onProgress KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/ArduinoOTA/library.properties b/libraries/ArduinoOTA/library.properties new file mode 100644 index 00000000..854d4959 --- /dev/null +++ b/libraries/ArduinoOTA/library.properties @@ -0,0 +1,10 @@ +name=ArduinoOTA +version=1.0 +author=Ivan Grokhotkov and Miguel Angel Ajo +maintainer=Earle F. Philhower, III +sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download. +paragraph=With this library you can enable your sketch to be upgraded over network. Includes mdns announces to get discovered by the arduino IDE. +category=Communication +url=https://github.com/earlephilhower/arduino-pico +architectures=rp2040 +dot_a_linkage=true diff --git a/libraries/ArduinoOTA/src/ArduinoOTA.cpp b/libraries/ArduinoOTA/src/ArduinoOTA.cpp new file mode 100644 index 00000000..e60f28ea --- /dev/null +++ b/libraries/ArduinoOTA/src/ArduinoOTA.cpp @@ -0,0 +1,398 @@ +#include +#include +#include "ArduinoOTA.h" +#include "MD5Builder.h" +#include +#include + +#include "lwip/udp.h" +#include "include/UdpContext.h" + +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) +#include +#endif + +//#ifdef DEBUG_ESP_OTA +//#ifdef DEBUG_ESP_PORT +//#define OTA_DEBUG DEBUG_ESP_PORT +//#endif +//#endif +#define OTA_DEBUG Serial + +ArduinoOTAClass::ArduinoOTAClass() { +} + +ArduinoOTAClass::~ArduinoOTAClass() { + if (_udp_ota) { + _udp_ota->unref(); + _udp_ota = 0; + } +} + +void ArduinoOTAClass::onStart(THandlerFunction fn) { + _start_callback = fn; +} + +void ArduinoOTAClass::onEnd(THandlerFunction fn) { + _end_callback = fn; +} + +void ArduinoOTAClass::onProgress(THandlerFunction_Progress fn) { + _progress_callback = fn; +} + +void ArduinoOTAClass::onError(THandlerFunction_Error fn) { + _error_callback = fn; +} + +void ArduinoOTAClass::setPort(uint16_t port) { + if (!_initialized && !_port && port) { + _port = port; + } +} + +void ArduinoOTAClass::setHostname(const char * hostname) { + if (!_initialized && !_hostname.length() && hostname) { + _hostname = hostname; + } +} + +String ArduinoOTAClass::getHostname() { + return _hostname; +} + +void ArduinoOTAClass::setPassword(const char * password) { + if (!_initialized && !_password.length() && password) { + MD5Builder passmd5; + passmd5.begin(); + passmd5.add(password); + passmd5.calculate(); + _password = passmd5.toString(); + } +} + +void ArduinoOTAClass::setPasswordHash(const char * password) { + if (!_initialized && !_password.length() && password) { + _password = password; + } +} + +void ArduinoOTAClass::setRebootOnSuccess(bool reboot) { + _rebootOnSuccess = reboot; +} + +void ArduinoOTAClass::begin(bool useMDNS) { + if (_initialized) { + return; + } + + _useMDNS = useMDNS; + + if (!_hostname.length()) { + char tmp[15]; + sprintf(tmp, "pico-%s", rp2040.getChipID()); + _hostname = tmp; + } + if (!_port) { + _port = 2040; + } + + if (_udp_ota) { + _udp_ota->unref(); + _udp_ota = 0; + } + + _udp_ota = new UdpContext; + _udp_ota->ref(); + + if (!_udp_ota->listen(IP_ADDR_ANY, _port)) { + return; + } + _udp_ota->onRx(std::bind(&ArduinoOTAClass::_onRx, this)); + +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) + if (_useMDNS) { + MDNS.begin(_hostname.c_str()); + + if (_password.length()) { + MDNS.enableArduino(_port, true); + } else { + MDNS.enableArduino(_port); + } + } +#endif + _initialized = true; + _state = OTA_IDLE; +#ifdef OTA_DEBUG + OTA_DEBUG.printf("OTA server at: %s.local:%u\n", _hostname.c_str(), _port); +#endif +} + +int ArduinoOTAClass::parseInt() { + char data[16]; + uint8_t index; + char value; + while (_udp_ota->peek() == ' ') { + _udp_ota->read(); + } + for (index = 0; index < sizeof(data); ++index) { + value = _udp_ota->peek(); + if (value < '0' || value > '9') { + data[index] = '\0'; + return atoi(data); + } + data[index] = _udp_ota->read(); + } + return 0; +} + +String ArduinoOTAClass::readStringUntil(char end) { + String res; + int value; + while (true) { + value = _udp_ota->read(); + if (value < 0 || value == '\0' || value == end) { + return res; + } + res += static_cast(value); + } + return res; +} + +void ArduinoOTAClass::_onRx() { + if (!_udp_ota->next()) { + return; + } + IPAddress ota_ip; + + if (_state == OTA_IDLE) { + int cmd = parseInt(); + if (cmd != U_FLASH && cmd != U_FS) { + return; + } + _ota_ip = _udp_ota->getRemoteAddress(); + _cmd = cmd; + _ota_port = parseInt(); + _ota_udp_port = _udp_ota->getRemotePort(); + _size = parseInt(); + _udp_ota->read(); + _md5 = readStringUntil('\n'); + _md5.trim(); + if (_md5.length() != 32) { + return; + } + + ota_ip = _ota_ip; + + if (_password.length()) { + MD5Builder nonce_md5; + nonce_md5.begin(); + nonce_md5.add(String(micros())); + nonce_md5.calculate(); + _nonce = nonce_md5.toString(); + + char auth_req[38]; + sprintf(auth_req, "AUTH %s", _nonce.c_str()); + _udp_ota->append((const char *)auth_req, strlen(auth_req)); + _udp_ota->send(ota_ip, _ota_udp_port); + _state = OTA_WAITAUTH; + return; + } else { + _state = OTA_RUNUPDATE; + } + } else if (_state == OTA_WAITAUTH) { + int cmd = parseInt(); + if (cmd != U_AUTH) { + _state = OTA_IDLE; + return; + } + _udp_ota->read(); + String cnonce = readStringUntil(' '); + String response = readStringUntil('\n'); + if (cnonce.length() != 32 || response.length() != 32) { + _state = OTA_IDLE; + return; + } + + String challenge = _password + ':' + String(_nonce) + ':' + cnonce; + MD5Builder _challengemd5; + _challengemd5.begin(); + _challengemd5.add(challenge); + _challengemd5.calculate(); + String result = _challengemd5.toString(); + + ota_ip = _ota_ip; + // if(result.equalsConstantTime(response)) { + if (result.equals(response)) { + _state = OTA_RUNUPDATE; + } else { + _udp_ota->append("Authentication Failed", 21); + _udp_ota->send(ota_ip, _ota_udp_port); + if (_error_callback) { + _error_callback(OTA_AUTH_ERROR); + } + _state = OTA_IDLE; + } + } + + while (_udp_ota->next()) { + _udp_ota->flush(); + } +} + +void ArduinoOTAClass::_runUpdate() { + IPAddress ota_ip = _ota_ip; + + if (!Update.begin(_size, _cmd)) { +#ifdef OTA_DEBUG + OTA_DEBUG.println("Update Begin Error"); +#endif + if (_error_callback) { + _error_callback(OTA_BEGIN_ERROR); + } + + StreamString ss; + Update.printError(ss); + _udp_ota->append("ERR: ", 5); + _udp_ota->append(ss.c_str(), ss.length()); + _udp_ota->send(ota_ip, _ota_udp_port); + delay(100); + _udp_ota->listen(IP_ADDR_ANY, _port); + _state = OTA_IDLE; + return; + } + if (!LittleFS.begin()) { + _udp_ota->append("ERR: ", 5); + _udp_ota->append("nofilesystem", 6); + _udp_ota->send(ota_ip, _ota_udp_port); + delay(100); + _udp_ota->listen(IP_ADDR_ANY, _port); + _state = OTA_IDLE; + return; + } + + _udp_ota->append("OK", 2); + _udp_ota->send(ota_ip, _ota_udp_port); + delay(100); + + Update.setMD5(_md5.c_str()); + + if (_start_callback) { + _start_callback(); + } + if (_progress_callback) { + _progress_callback(0, _size); + } + + WiFiClient client; + if (!client.connect(_ota_ip, _ota_port)) { +#ifdef OTA_DEBUG + OTA_DEBUG.printf("Connect Failed\n"); +#endif + _udp_ota->listen(IP_ADDR_ANY, _port); + if (_error_callback) { + _error_callback(OTA_CONNECT_ERROR); + } + _state = OTA_IDLE; + } + // OTA sends little packets + client.setNoDelay(true); + + uint32_t written, total = 0; + while (!Update.isFinished() && (client.connected() || client.available())) { + int waited = 1000; + while (!client.available() && waited--) { + delay(1); + } + if (!waited) { +#ifdef OTA_DEBUG + OTA_DEBUG.printf("Receive Failed\n"); +#endif + _udp_ota->listen(IP_ADDR_ANY, _port); + if (_error_callback) { + _error_callback(OTA_RECEIVE_ERROR); + } + _state = OTA_IDLE; + } + written = Update.write(client); + if (written > 0) { + client.print(written, DEC); + total += written; + if (_progress_callback) { + _progress_callback(total, _size); + } + } + } + + + if (Update.end()) { + // Ensure last count packet has been sent out and not combined with the final OK + client.flush(); + delay(1000); + client.print("OK"); + client.flush(); + delay(1000); + client.stop(); +#ifdef OTA_DEBUG + OTA_DEBUG.printf("Update Success\n"); +#endif + if (_end_callback) { + _end_callback(); + } + if (_rebootOnSuccess) { +#ifdef OTA_DEBUG + OTA_DEBUG.printf("Rebooting...\n"); +#endif + LittleFS.end(); + //let serial/network finish tasks that might be given in _end_callback + delay(100); + rp2040.reboot(); + } + } else { + _udp_ota->listen(IP_ADDR_ANY, _port); + if (_error_callback) { + _error_callback(OTA_END_ERROR); + } + Update.printError(client); +#ifdef OTA_DEBUG + Update.printError(OTA_DEBUG); +#endif + _state = OTA_IDLE; + } +} + +void ArduinoOTAClass::end() { + _initialized = false; + _udp_ota->unref(); + _udp_ota = 0; +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) + if (_useMDNS) { + MDNS.end(); + } +#endif + _state = OTA_IDLE; +#ifdef OTA_DEBUG + OTA_DEBUG.printf("OTA server stopped.\n"); +#endif +} +//this needs to be called in the loop() +void ArduinoOTAClass::handle() { + if (_state == OTA_RUNUPDATE) { + _runUpdate(); + _state = OTA_IDLE; + } + +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) + if (_useMDNS) { + MDNS.update(); //handle MDNS update as well, given that ArduinoOTA relies on it anyways + } +#endif +} + +int ArduinoOTAClass::getCommand() { + return _cmd; +} + +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA) +ArduinoOTAClass ArduinoOTA; +#endif diff --git a/libraries/ArduinoOTA/src/ArduinoOTA.h b/libraries/ArduinoOTA/src/ArduinoOTA.h new file mode 100644 index 00000000..c236b748 --- /dev/null +++ b/libraries/ArduinoOTA/src/ArduinoOTA.h @@ -0,0 +1,103 @@ +#pragma once + +#include +#include +#include +#include + +class UdpContext; + +typedef enum { + OTA_IDLE, + OTA_WAITAUTH, + OTA_RUNUPDATE +} ota_state_t; + +typedef enum { + OTA_AUTH_ERROR, + OTA_BEGIN_ERROR, + OTA_CONNECT_ERROR, + OTA_RECEIVE_ERROR, + OTA_END_ERROR +} ota_error_t; + + +class ArduinoOTAClass { +public: + typedef std::function THandlerFunction; + typedef std::function THandlerFunction_Error; + typedef std::function THandlerFunction_Progress; + + ArduinoOTAClass(); + ~ArduinoOTAClass(); + + //Sets the service port. Default 2040 + void setPort(uint16_t port); + + //Sets the device hostname. Default pico-xxxxxx + void setHostname(const char *hostname); + String getHostname(); + + //Sets the password that will be required for OTA. Default NULL + void setPassword(const char *password); + + //Sets the password as above but in the form MD5(password). Default NULL + void setPasswordHash(const char *password); + + //Sets if the device should be rebooted after successful update. Default true + void setRebootOnSuccess(bool reboot); + + //This callback will be called when OTA connection has begun + void onStart(THandlerFunction fn); + + //This callback will be called when OTA has finished + void onEnd(THandlerFunction fn); + + //This callback will be called when OTA encountered Error + void onError(THandlerFunction_Error fn); + + //This callback will be called when OTA is receiving data + void onProgress(THandlerFunction_Progress fn); + + //Starts the ArduinoOTA service + void begin(bool useMDNS = true); + + //Ends the ArduinoOTA service + void end(); + //Call this in loop() to run the service. Also calls MDNS.update() when begin() or begin(true) is used. + void handle(); + + //Gets update command type after OTA has started. Either U_FLASH or U_FS + int getCommand(); + +private: + void _runUpdate(void); + void _onRx(void); + int parseInt(void); + String readStringUntil(char end); + + int _port = 0; + String _password; + String _hostname; + String _nonce; + UdpContext *_udp_ota = nullptr; + bool _initialized = false; + bool _rebootOnSuccess = true; + bool _useMDNS = true; + ota_state_t _state = OTA_IDLE; + int _size = 0; + int _cmd = 0; + uint16_t _ota_port = 0; + uint16_t _ota_udp_port = 0; + IPAddress _ota_ip; + String _md5; + + THandlerFunction _start_callback = nullptr; + THandlerFunction _end_callback = nullptr; + THandlerFunction_Error _error_callback = nullptr; + THandlerFunction_Progress _progress_callback = nullptr; +}; + +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_ARDUINOOTA) +extern ArduinoOTAClass ArduinoOTA; +#endif diff --git a/libraries/FreeRTOS/src/FreeRTOSConfig.h b/libraries/FreeRTOS/src/FreeRTOSConfig.h index eccf04d8..f8279192 100644 --- a/libraries/FreeRTOS/src/FreeRTOSConfig.h +++ b/libraries/FreeRTOS/src/FreeRTOSConfig.h @@ -35,8 +35,8 @@ extern void __register_impure_ptr(struct _reent *p); #define portSET_IMPURE_PTR(x) __register_impure_ptr(x) /* Run time stats related definitions. */ -void vMainConfigureTimerForRunTimeStats( void ); -unsigned long ulMainGetRunTimeCounterValue( void ); +void vMainConfigureTimerForRunTimeStats(void); +unsigned long ulMainGetRunTimeCounterValue(void); #define configGENERATE_RUN_TIME_STATS 1 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() //vMainConfigureTimerForRunTimeStats() #define portGET_RUN_TIME_COUNTER_VALUE() ulMainGetRunTimeCounterValue() @@ -51,8 +51,8 @@ unsigned long ulMainGetRunTimeCounterValue( void ); #define configTIMER_QUEUE_LENGTH 5 #define configTIMER_TASK_STACK_DEPTH ( 1024 ) -/* Set the following definitions to 1 to include the API function, or zero -to exclude the API function. */ +/* Set the following definitions to 1 to include the API function, or zero + to exclude the API function. */ #define INCLUDE_xTaskGetCurrentTaskHandle 1 #define INCLUDE_vTaskPrioritySet 1 #define INCLUDE_uxTaskPriorityGet 1 @@ -63,10 +63,10 @@ to exclude the API function. */ #define INCLUDE_vTaskDelay 1 #define INCLUDE_eTaskGetState 1 -/* This demo makes use of one or more example stats formatting functions. These -format the raw data provided by the uxTaskGetSystemState() function in to human -readable ASCII form. See the notes in the implementation of vTaskList() within -FreeRTOS/Source/tasks.c for limitations. */ +/* This demo makes use of one or more example stats formatting functions. These + format the raw data provided by the uxTaskGetSystemState() function in to human + readable ASCII form. See the notes in the implementation of vTaskList() within + FreeRTOS/Source/tasks.c for limitations. */ #define configUSE_STATS_FORMATTING_FUNCTIONS 1 #define configUSE_MUTEXES 1 @@ -74,50 +74,50 @@ FreeRTOS/Source/tasks.c for limitations. */ #define INCLUDE_xTaskGetIdleTaskHandle 1 #define configUSE_MALLOC_FAILED_HOOK 1 #define configCHECK_FOR_STACK_OVERFLOW 2 -/* Normal assert() semantics without relying on the provision of an assert.h -header file. */ +/* Normal assert() semantics without relying on the provision of an assert.h + header file. */ /* Cortex-M specific definitions. */ #undef __NVIC_PRIO_BITS #ifdef __NVIC_PRIO_BITS - /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ - #define configPRIO_BITS __NVIC_PRIO_BITS +/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ +#define configPRIO_BITS __NVIC_PRIO_BITS #else - #define configPRIO_BITS 3 /* 8 priority levels */ +#define configPRIO_BITS 3 /* 8 priority levels */ #endif -/* The lowest interrupt priority that can be used in a call to a "set priority" -function. */ +/* The lowest interrupt priority that can be used in a call to a "set priority" + function. */ #define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0x7 -/* The highest interrupt priority that can be used by any interrupt service -routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL -INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER -PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +/* The highest interrupt priority that can be used by any interrupt service + routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL + INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER + PRIORITY THAN THIS! (higher priorities are lower numeric values. */ #define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 -/* Interrupt priorities used by the kernel port layer itself. These are generic -to all Cortex-M ports, and do not rely on any particular library functions. */ +/* Interrupt priorities used by the kernel port layer itself. These are generic + to all Cortex-M ports, and do not rely on any particular library functions. */ #define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) /* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! -See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ + See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ #define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) extern void rtosFatalError(void); #define configASSERT( x ) \ if( ( x ) == 0 ) { portDISABLE_INTERRUPTS(); rtosFatalError(); } -/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS -standard names - or at least those used in the unmodified vector table. */ +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS + standard names - or at least those used in the unmodified vector table. */ //#define xPortPendSVHandler PendSV_Handler //#define xPortSysTickHandler SysTick_Handler //#define vPortSVCHandler SVC_Handler -/* The size of the global output buffer that is available for use when there -are multiple command interpreters running at once (for example, one on a UART -and one on TCP/IP). This is done to prevent an output buffer being defined by -each implementation - which would waste RAM. In this case, there is only one -command interpreter running. */ +/* The size of the global output buffer that is available for use when there + are multiple command interpreters running at once (for example, one on a UART + and one on TCP/IP). This is done to prevent an output buffer being defined by + each implementation - which would waste RAM. In this case, there is only one + command interpreter running. */ #define configCOMMAND_INT_MAX_OUTPUT_SIZE 2048 diff --git a/libraries/FreeRTOS/src/variantHooks.cpp b/libraries/FreeRTOS/src/variantHooks.cpp index 49624689..4ba8fbcd 100644 --- a/libraries/FreeRTOS/src/variantHooks.cpp +++ b/libraries/FreeRTOS/src/variantHooks.cpp @@ -1,28 +1,28 @@ /* - * Copyright (C) 2021 Phillip Stevens All Rights Reserved. - * Modifications by Earle F. Philhower, III, for Arduino-Pico - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * - * This file is NOT part of the FreeRTOS distribution. - * - */ + Copyright (C) 2021 Phillip Stevens All Rights Reserved. + Modifications by Earle F. Philhower, III, for Arduino-Pico + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + the Software, and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + + This file is NOT part of the FreeRTOS distribution. + +*/ #include /* Arduino Core includes */ @@ -42,8 +42,7 @@ /*-----------------------------------------------------------*/ -void initFreeRTOS(void) -{ +void initFreeRTOS(void) { } extern void setup() __attribute__((weak)); @@ -54,8 +53,7 @@ extern void loop1() __attribute__((weak)); extern void __loop(); volatile bool __usbInitted = false; -static void __core0(void *params) -{ +static void __core0(void *params) { (void) params; #ifndef NO_USB while (!__usbInitted) { @@ -77,8 +75,7 @@ static void __core0(void *params) } } -static void __core1(void *params) -{ +static void __core1(void *params) { (void) params; #ifndef NO_USB while (!__usbInitted) { @@ -97,7 +94,7 @@ static void __core1(void *params) vTaskDelay(1000); } } -} +} extern "C" void delay(unsigned long ms) { vTaskDelay(ms / portTICK_PERIOD_MS); @@ -111,17 +108,16 @@ extern mutex_t __usb_mutex; static TaskHandle_t __usbTask; static void __usb(void *param); -void startFreeRTOS(void) -{ +void startFreeRTOS(void) { TaskHandle_t c0; xTaskCreate(__core0, "CORE0", 1024, 0, configMAX_PRIORITIES / 2, &c0); - vTaskCoreAffinitySet( c0, 1 << 0 ); + vTaskCoreAffinitySet(c0, 1 << 0); if (setup1 || loop1) { TaskHandle_t c1; xTaskCreate(__core1, "CORE1", 1024, 0, configMAX_PRIORITIES / 2, &c1); - vTaskCoreAffinitySet( c1, 1 << 1 ); + vTaskCoreAffinitySet(c1, 1 << 1); } // Initialise and run the freeRTOS scheduler. Execution should never return here. @@ -135,33 +131,30 @@ void startFreeRTOS(void) /*-----------------------------------------------------------*/ -void prvDisableInterrupts() -{ +void prvDisableInterrupts() { portDISABLE_INTERRUPTS(); } -void prvEnableInterrupts() -{ +void prvEnableInterrupts() { portENABLE_INTERRUPTS(); } /*-----------------------------------------------------------*/ #if ( configUSE_IDLE_HOOK == 1 ) /* - * Call the user defined loop() function from within the idle task. - * This allows the application designer to add background functionality - * without the overhead of a separate task. - * - * NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. - * - */ + Call the user defined loop() function from within the idle task. + This allows the application designer to add background functionality + without the overhead of a separate task. + + NOTE: vApplicationIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. + +*/ extern "C" -void vApplicationIdleHook( void ) __attribute__((weak)); +void vApplicationIdleHook(void) __attribute__((weak)); -void vApplicationIdleHook( void ) -{ +void vApplicationIdleHook(void) { __wfe(); // Low power idle if nothing to do... } @@ -170,22 +163,21 @@ void vApplicationIdleHook( void ) #if ( configUSE_MINIMAL_IDLE_HOOK == 1 ) /* - * Call the user defined minimalIdle() function from within the idle task. - * This allows the application designer to add background functionality - * without the overhead of a separate task. - * - * NOTE: vApplicationMinimalIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. - * - */ -void minimalIdle( void ) __attribute__((weak)); + Call the user defined minimalIdle() function from within the idle task. + This allows the application designer to add background functionality + without the overhead of a separate task. + + NOTE: vApplicationMinimalIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. + +*/ +void minimalIdle(void) __attribute__((weak)); void minimalIdle() {} //Empty minimalIdle function extern "C" -void vApplicationMinimalIdleHook( void ) __attribute__((weak)); +void vApplicationMinimalIdleHook(void) __attribute__((weak)); -void vApplicationMinimalIdleHook( void ) -{ - minimalIdle(); +void vApplicationMinimalIdleHook(void) { + minimalIdle(); } #endif /* configUSE_MINIMAL_IDLE_HOOK == 1 */ @@ -193,22 +185,21 @@ void vApplicationMinimalIdleHook( void ) #if ( configUSE_TICK_HOOK == 1 ) /* - * Call the user defined minimalIdle() function from within the idle task. - * This allows the application designer to add background functionality - * without the overhead of a separate task. - * - * NOTE: vApplicationMinimalIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. - * - */ -void tick( void ) __attribute__((weak)); + Call the user defined minimalIdle() function from within the idle task. + This allows the application designer to add background functionality + without the overhead of a separate task. + + NOTE: vApplicationMinimalIdleHook() MUST NOT, UNDER ANY CIRCUMSTANCES, CALL A FUNCTION THAT MIGHT BLOCK. + +*/ +void tick(void) __attribute__((weak)); void tick() {} //Empty minimalIdle function extern "C" -void vApplicationTickHook( void ) __attribute__((weak)); +void vApplicationTickHook(void) __attribute__((weak)); -void vApplicationTickHook( void ) -{ - tick(); +void vApplicationTickHook(void) { + tick(); } #endif /* configUSE_TICK_HOOK == 1 */ @@ -217,37 +208,33 @@ void vApplicationTickHook( void ) #if ( configUSE_MALLOC_FAILED_HOOK == 1 || configCHECK_FOR_STACK_OVERFLOW >= 1 || configDEFAULT_ASSERT == 1 ) /** - * Private function to enable board led to use it in application hooks - */ -void prvSetMainLedOn( void ) -{ - gpio_init(LED_BUILTIN); - gpio_set_dir(LED_BUILTIN, true); - gpio_put(LED_BUILTIN, true); + Private function to enable board led to use it in application hooks +*/ +void prvSetMainLedOn(void) { + gpio_init(LED_BUILTIN); + gpio_set_dir(LED_BUILTIN, true); + gpio_put(LED_BUILTIN, true); } /** - * Private function to blink board led to use it in application hooks - */ -void prvBlinkMainLed( void ) -{ - gpio_put(LED_BUILTIN, !gpio_get(LED_BUILTIN)); + Private function to blink board led to use it in application hooks +*/ +void prvBlinkMainLed(void) { + gpio_put(LED_BUILTIN, !gpio_get(LED_BUILTIN)); } #endif -/*---------------------------------------------------------------------------*\ -Usage: +/* ---------------------------------------------------------------------------*\ + Usage: called on fatal error (interrupts disabled already) -\*---------------------------------------------------------------------------*/ + \*---------------------------------------------------------------------------*/ extern "C" -void rtosFatalError(void) -{ +void rtosFatalError(void) { prvSetMainLedOn(); // Main LED on. - - for(;;) - { - // Main LED slow flash + + for (;;) { + // Main LED slow flash sleep_ms(100); prvBlinkMainLed(); sleep_ms(2000); @@ -256,30 +243,28 @@ void rtosFatalError(void) } #if ( configUSE_MALLOC_FAILED_HOOK == 1 ) -/*---------------------------------------------------------------------------*\ -Usage: +/* ---------------------------------------------------------------------------*\ + Usage: called by task system when a malloc failure is noticed -Description: + Description: Malloc failure handler -- Shut down all interrupts, send serious complaint to command port. FAST Blink on main LED. -Arguments: + Arguments: pxTask - pointer to task handle pcTaskName - pointer to task name -Results: + Results: -Notes: + Notes: This routine will never return. This routine is referenced in the task.c file of FreeRTOS as an extern. -\*---------------------------------------------------------------------------*/ + \*---------------------------------------------------------------------------*/ extern "C" -void vApplicationMallocFailedHook( void ) __attribute__((weak)); +void vApplicationMallocFailedHook(void) __attribute__((weak)); -void vApplicationMallocFailedHook( void ) -{ +void vApplicationMallocFailedHook(void) { prvSetMainLedOn(); // Main LED on. - - for(;;) - { + + for (;;) { sleep_ms(50); prvBlinkMainLed(); // Main LED fast blink. } @@ -292,16 +277,14 @@ void vApplicationMallocFailedHook( void ) #if ( configCHECK_FOR_STACK_OVERFLOW >= 1 ) extern "C" -void vApplicationStackOverflowHook( TaskHandle_t xTask, - char * pcTaskName ) __attribute__((weak)); +void vApplicationStackOverflowHook(TaskHandle_t xTask, + char * pcTaskName) __attribute__((weak)); -void vApplicationStackOverflowHook( TaskHandle_t xTask __attribute__((unused)), - char * pcTaskName __attribute__((unused)) ) -{ +void vApplicationStackOverflowHook(TaskHandle_t xTask __attribute__((unused)), + char * pcTaskName __attribute__((unused))) { prvSetMainLedOn(); // Main LED on. - for(;;) - { + for (;;) { sleep_ms(2000); prvBlinkMainLed(); // Main LED slow blink. } @@ -313,14 +296,13 @@ void vApplicationStackOverflowHook( TaskHandle_t xTask __attribute__((unused)), #if ( configSUPPORT_STATIC_ALLOCATION >= 1 ) extern "C" -void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, - StackType_t ** ppxIdleTaskStackBuffer, - configSTACK_DEPTH_TYPE * pulIdleTaskStackSize ) __attribute__((weak)); +void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + configSTACK_DEPTH_TYPE * pulIdleTaskStackSize) __attribute__((weak)); -void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, - StackType_t ** ppxIdleTaskStackBuffer, - configSTACK_DEPTH_TYPE * pulIdleTaskStackSize ) -{ +void vApplicationGetIdleTaskMemory(StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + configSTACK_DEPTH_TYPE * pulIdleTaskStackSize) { static StaticTask_t xIdleTaskTCB; static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; @@ -332,14 +314,13 @@ void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, #if ( configUSE_TIMERS >= 1 ) extern "C" -void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, - StackType_t ** ppxTimerTaskStackBuffer, - configSTACK_DEPTH_TYPE * pulTimerTaskStackSize ) __attribute__((weak)); +void vApplicationGetTimerTaskMemory(StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + configSTACK_DEPTH_TYPE * pulTimerTaskStackSize) __attribute__((weak)); -void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, - StackType_t ** ppxTimerTaskStackBuffer, - configSTACK_DEPTH_TYPE * pulTimerTaskStackSize ) -{ +void vApplicationGetTimerTaskMemory(StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + configSTACK_DEPTH_TYPE * pulTimerTaskStackSize) { static StaticTask_t xTimerTaskTCB; static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; @@ -353,8 +334,8 @@ void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, #endif /* configSUPPORT_STATIC_ALLOCATION >= 1 */ /** - * configASSERT default implementation - */ + configASSERT default implementation +*/ #if configDEFAULT_ASSERT == 1 extern "C" @@ -363,8 +344,7 @@ void vApplicationAssertHook() { taskDISABLE_INTERRUPTS(); // Disable task interrupts prvSetMainLedOn(); // Main LED on. - for(;;) - { + for (;;) { sleep_ms(100); prvBlinkMainLed(); // Led off. @@ -381,8 +361,7 @@ void vApplicationAssertHook() { #endif -static void __usb(void *param) -{ +static void __usb(void *param) { (void) param; tusb_init(); @@ -403,8 +382,7 @@ static void __usb(void *param) extern void __SetupDescHIDReport(); extern void __SetupUSBDescriptor(); -void __USBStart() -{ +void __USBStart() { mutex_init(&__usb_mutex); __SetupDescHIDReport(); @@ -412,5 +390,5 @@ void __USBStart() // Make highest prio and locked to core 0 xTaskCreate(__usb, "USB", 256, 0, configMAX_PRIORITIES - 1, &__usbTask); - vTaskCoreAffinitySet( __usbTask, 1 << 0 ); + vTaskCoreAffinitySet(__usbTask, 1 << 0); } diff --git a/libraries/LEAmDNS/README.rst b/libraries/LEAmDNS/README.rst new file mode 100644 index 00000000..f14d8a41 --- /dev/null +++ b/libraries/LEAmDNS/README.rst @@ -0,0 +1,61 @@ +ESP8266 Multicast DNS +===================== + +A port of CC3000 Multicast DNS library (version 1.1) + +This is a simple implementation of multicast DNS query support for an +Arduino running on ESP8266 chip. Only support for resolving address +queries is currently implemented. + +Requirements +------------ + +- ESP8266WiFi library +- MDNS support in your operating system/client machines: +- For Mac OSX support is built in through Bonjour already. +- For Linux, install `Avahi `__. +- For Windows, install + `Bonjour `__. + +Usage +----- + +1. Download this repository as a zip (button on the right) and follow + `these instructions to install into + Arduino `__. +2. Include the ESP8266mDNS library in the sketch. +3. Call MDNS.begin method in the sketch's setup and provide a domain + name (without the '.local' suffix, i.e. just provide 'foo' to resolve + 'foo.local'). Optionally provide the IP address to advertise and time + to live (in seconds) for the DNS record -- the default is 1 hour. +4. To advertise DNS-SD services, call MDNS.addService(service, proto, + port), where service and proto are strings with service and protocol + name (e.g. "http", "tcp"), and port is an integer port number for + this service (e.g. 80). + +See the included MDNS + HTTP server sketch for a full example. + +License +------- + +Copyright (c) 2013 Tony DiCola (tony@tonydicola.com) ESP8266 port (c) +2015 Ivan Grokhotkov (ivan@esp8266.com) + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/libraries/LEAmDNS/keywords.txt b/libraries/LEAmDNS/keywords.txt new file mode 100644 index 00000000..6b2f0395 --- /dev/null +++ b/libraries/LEAmDNS/keywords.txt @@ -0,0 +1,25 @@ +####################################### +# Syntax Coloring Map For Ultrasound +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +ESP8266mDNS KEYWORD1 +MDNSResponder KEYWORD1 +MDNS KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +update KEYWORD2 +addService KEYWORD2 +enableArduino KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/LEAmDNS/library.properties b/libraries/LEAmDNS/library.properties new file mode 100644 index 00000000..3cef765f --- /dev/null +++ b/libraries/LEAmDNS/library.properties @@ -0,0 +1,10 @@ +name=LEAmDNS +version=1.2 +author=multiple, see files +maintainer=LaborEtArs +sentence=Creates a mDNS responder. +paragraph=Creates a mDNS responder to ensure host domain uniqueness in local networks and to allow for mDNS service discovery and announcement. +category=Communication +url=https://github.com/LaborEtArs/ESP8266mDNS +architectures=rp2040 +dot_a_linkage=true diff --git a/libraries/LEAmDNS/src/ESP8266mDNS.cpp b/libraries/LEAmDNS/src/ESP8266mDNS.cpp new file mode 100644 index 00000000..821b7010 --- /dev/null +++ b/libraries/LEAmDNS/src/ESP8266mDNS.cpp @@ -0,0 +1,32 @@ +/* + + License (MIT license): + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ +#include + +/* + MDNS responder global instance + + Class type that is instantiated depends on the type mapping in ESP8266mDNS.h +*/ +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) +MDNSResponder MDNS; +#endif diff --git a/libraries/LEAmDNS/src/ESP8266mDNS.h b/libraries/LEAmDNS/src/ESP8266mDNS.h new file mode 100644 index 00000000..5bfd3daf --- /dev/null +++ b/libraries/LEAmDNS/src/ESP8266mDNS.h @@ -0,0 +1,54 @@ +/* + ESP8266mDNS.h - mDNSResponder for ESP8266 family + This file is part of the esp8266 core for Arduino environment. + + mDNS implementation, that supports many mDNS features like: + - Presenting a DNS-SD service to interested observers, eg. a http server by presenting + _http._tcp service + - Support for multi-level compressed names in input; in output only a very simple one-leven + full-name compression is implemented + - Probing host and service domains for uniqueness in the local network + - Tiebreaking while probing is supported in a very minimalistic way (the 'higher' IP address + wins the tiebreak) + - Announcing available services after successful probing + - Using fixed service TXT items or + - Using dynamic service TXT items for presented services (via callback) + - Remove services (and un-announcing them to the observers by sending goodbye-messages) + - Static queries for DNS-SD services (creating a fixed answer set after a certain timeout + period) + - Dynamic queries for DNS-SD services with cached and updated answers and user notifications + - Support for multi-homed client host domains + + See 'src/LEAmDNS.h' for implementation details, configuration and usage information. + See 'examples/LEAmDNS/' for examples of the new features. + + LEAmDNS is expected to be compatible with the original ESP8266mDNS implementation, and it can be + used as a drop-in replacement in existing projects. + + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#pragma once + +#include "LEAmDNS.h" // LEA + +#if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_MDNS) +// Maps the implementation to use to the global namespace type +using MDNSResponder = esp8266::MDNSImplementation::MDNSResponder; // LEA + +extern MDNSResponder MDNS; +#endif diff --git a/libraries/LEAmDNS/src/LEAmDNS.cpp b/libraries/LEAmDNS/src/LEAmDNS.cpp new file mode 100644 index 00000000..ef86b560 --- /dev/null +++ b/libraries/LEAmDNS/src/LEAmDNS.cpp @@ -0,0 +1,1244 @@ +/* + LEAmDNS.cpp + + License (MIT license): + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +//#include +#include + +#include "ESP8266mDNS.h" +#include "LEAmDNS_Priv.h" +#include // LwipIntf::stateUpCB() +#include // LwipIntf::stateUpCB() +#include +#include + +namespace esp8266 { + +/* + LEAmDNS +*/ +namespace MDNSImplementation { + +/** + STRINGIZE +*/ +#ifndef STRINGIZE +#define STRINGIZE(x) #x +#endif +#ifndef STRINGIZE_VALUE_OF +#define STRINGIZE_VALUE_OF(x) STRINGIZE(x) +#endif + +/** + INTERFACE +*/ + +/** + MDNSResponder::MDNSResponder +*/ +MDNSResponder::MDNSResponder(void) : + m_pServices(0), m_pUDPContext(0), m_pcHostname(0), m_pServiceQueries(0), + m_fnServiceTxtCallback(0) { +} + +/* + MDNSResponder::~MDNSResponder +*/ +MDNSResponder::~MDNSResponder(void) { + _resetProbeStatus(false); + _releaseServiceQueries(); + _releaseHostname(); + _releaseUDPContext(); + _releaseServices(); +} + +/* + MDNSResponder::begin + + Set the host domain (for probing) and install WiFi event handlers for + IP assignment and disconnection management. In both cases, the MDNS responder + is restarted (reset and restart probe status) + Finally the responder is (re)started + +*/ +bool MDNSResponder::begin(const char* p_pcHostname, const IPAddress& /*p_IPAddress*/, + uint32_t /*p_u32TTL*/) { + bool bResult = false; + + if (_setHostname(p_pcHostname)) { + bResult = _restart(); + } + + LwipIntf::stateUpCB( + [this](netif * intf) { + (void)intf; + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] new Interface '%c%c' is UP! restarting\n"), intf->name[0], + intf->name[1])); + _restart(); + }); + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] begin: FAILED for '%s'!\n"), + (p_pcHostname ? : "-")); + }); + + return bResult; +} + +/* + MDNSResponder::close + + Ends the MDNS responder. + Announced services are unannounced (by multicasting a goodbye message) + +*/ +bool MDNSResponder::close(void) { + bool bResult = false; + + if (0 != m_pUDPContext) { + _announce(false, true); + _resetProbeStatus(false); // Stop probing + _releaseServiceQueries(); + _releaseServices(); + _releaseUDPContext(); + _releaseHostname(); + + bResult = true; + } else { + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] close: Ignoring call to close!\n"));); + } + return bResult; +} + +/* + MDNSResponder::end + + Ends the MDNS responder. + for compatibility with esp32 + +*/ + +bool MDNSResponder::end(void) { + return close(); +} + +/* + MDNSResponder::setHostname + + Replaces the current hostname and restarts probing. + For services without own instance name (when the host name was used a instance + name), the instance names are replaced also (and the probing is restarted). + +*/ +bool MDNSResponder::setHostname(const char* p_pcHostname) { + bool bResult = false; + + if (_setHostname(p_pcHostname)) { + m_HostProbeInformation.m_ProbingStatus = ProbingStatus_ReadyToStart; + + // Replace 'auto-set' service names + bResult = true; + for (stcMDNSService* pService = m_pServices; ((bResult) && (pService)); + pService = pService->m_pNext) { + if (pService->m_bAutoName) { + bResult = pService->setName(p_pcHostname); + pService->m_ProbeInformation.m_ProbingStatus = ProbingStatus_ReadyToStart; + } + } + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] setHostname: FAILED for '%s'!\n"), + (p_pcHostname ? : "-")); + }); + return bResult; +} + +/* + MDNSResponder::setHostname (LEGACY) +*/ +bool MDNSResponder::setHostname(const String& p_strHostname) { + return setHostname(p_strHostname.c_str()); +} + +/* + SERVICES +*/ + +/* + MDNSResponder::addService + + Add service; using hostname if no name is explicitly provided for the service + The usual '_' underline, which is prepended to service and protocol, eg. _http, + may be given. If not, it is added automatically. + +*/ +MDNSResponder::hMDNSService MDNSResponder::addService(const char* p_pcName, + const char* p_pcService, + const char* p_pcProtocol, + uint16_t p_u16Port) { + hMDNSService hResult = 0; + + if (((!p_pcName) || // NO name OR + (MDNS_DOMAIN_LABEL_MAXLENGTH >= strlen(p_pcName))) + && // Fitting name + (p_pcService) && (MDNS_SERVICE_NAME_LENGTH >= strlen(p_pcService)) && (p_pcProtocol) + && ((MDNS_SERVICE_PROTOCOL_LENGTH - 1) != strlen(p_pcProtocol)) && (p_u16Port)) { + if (!_findService((p_pcName ? : m_pcHostname), p_pcService, + p_pcProtocol)) { // Not already used + if (0 + != (hResult = (hMDNSService)_allocService(p_pcName, p_pcService, p_pcProtocol, + p_u16Port))) { + // Start probing + ((stcMDNSService*)hResult)->m_ProbeInformation.m_ProbingStatus + = ProbingStatus_ReadyToStart; + } + } + } // else: bad arguments + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] addService: %s to add '%s.%s.%s'!\n"), + (hResult ? "Succeeded" : "FAILED"), (p_pcName ? : "-"), p_pcService, p_pcProtocol);); + DEBUG_EX_ERR(if (!hResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] addService: FAILED to add '%s.%s.%s'!\n"), + (p_pcName ? : "-"), p_pcService, p_pcProtocol); + }); + return hResult; +} + +/* + MDNSResponder::removeService + + Unanounce a service (by sending a goodbye message) and remove it + from the MDNS responder + +*/ +bool MDNSResponder::removeService(const MDNSResponder::hMDNSService p_hService) { + stcMDNSService* pService = 0; + bool bResult = (((pService = _findService(p_hService))) + && (_announceService(*pService, false)) && (_releaseService(pService))); + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] removeService: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::removeService +*/ +bool MDNSResponder::removeService(const char* p_pcName, const char* p_pcService, + const char* p_pcProtocol) { + return removeService( + (hMDNSService)_findService((p_pcName ? : m_pcHostname), p_pcService, p_pcProtocol)); +} + +/* + MDNSResponder::addService (LEGACY) +*/ +bool MDNSResponder::addService(const String& p_strService, const String& p_strProtocol, + uint16_t p_u16Port) { + return ( + 0 != addService(m_pcHostname, p_strService.c_str(), p_strProtocol.c_str(), p_u16Port)); +} + +/* + MDNSResponder::setServiceName +*/ +bool MDNSResponder::setServiceName(const MDNSResponder::hMDNSService p_hService, + const char* p_pcInstanceName) { + stcMDNSService* pService = 0; + bool bResult + = (((!p_pcInstanceName) || (MDNS_DOMAIN_LABEL_MAXLENGTH >= strlen(p_pcInstanceName))) + && ((pService = _findService(p_hService))) && (pService->setName(p_pcInstanceName)) + && ((pService->m_ProbeInformation.m_ProbingStatus = ProbingStatus_ReadyToStart))); + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] setServiceName: FAILED for '%s'!\n"), + (p_pcInstanceName ? : "-")); + }); + return bResult; +} + +/* + SERVICE TXT +*/ + +/* + MDNSResponder::addServiceTxt + + Add a static service TXT item ('Key'='Value') to a service. + +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addServiceTxt(const MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + const char* p_pcValue) { + hMDNSTxt hTxt = 0; + stcMDNSService* pService = _findService(p_hService); + if (pService) { + hTxt = (hMDNSTxt)_addServiceTxt(pService, p_pcKey, p_pcValue, false); + } + DEBUG_EX_ERR(if (!hTxt) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] addServiceTxt: FAILED for '%s=%s'!\n"), + (p_pcKey ? : "-"), (p_pcValue ? : "-")); + }); + return hTxt; +} + +/* + MDNSResponder::addServiceTxt (uint32_t) + + Formats: http://www.cplusplus.com/reference/cstdio/printf/ +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addServiceTxt(const MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + uint32_t p_u32Value) { + char acBuffer[32]; + *acBuffer = 0; + sprintf(acBuffer, "%u", (unsigned int)p_u32Value); + + return addServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addServiceTxt (uint16_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addServiceTxt(const MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + uint16_t p_u16Value) { + char acBuffer[16]; + *acBuffer = 0; + sprintf(acBuffer, "%hu", p_u16Value); + + return addServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addServiceTxt (uint8_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addServiceTxt(const MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + uint8_t p_u8Value) { + char acBuffer[8]; + *acBuffer = 0; + sprintf(acBuffer, "%hhu", p_u8Value); + + return addServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addServiceTxt (int32_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addServiceTxt(const MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + int32_t p_i32Value) { + char acBuffer[32]; + *acBuffer = 0; + sprintf(acBuffer, "%i", (int)p_i32Value); + + return addServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addServiceTxt (int16_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addServiceTxt(const MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + int16_t p_i16Value) { + char acBuffer[16]; + *acBuffer = 0; + sprintf(acBuffer, "%hi", p_i16Value); + + return addServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addServiceTxt (int8_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addServiceTxt(const MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + int8_t p_i8Value) { + char acBuffer[8]; + *acBuffer = 0; + sprintf(acBuffer, "%hhi", p_i8Value); + + return addServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::removeServiceTxt + + Remove a static service TXT item from a service. +*/ +bool MDNSResponder::removeServiceTxt(const MDNSResponder::hMDNSService p_hService, + const MDNSResponder::hMDNSTxt p_hTxt) { + bool bResult = false; + + stcMDNSService* pService = _findService(p_hService); + if (pService) { + stcMDNSServiceTxt* pTxt = _findServiceTxt(pService, p_hTxt); + if (pTxt) { + bResult = _releaseServiceTxt(pService, pTxt); + } + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] removeServiceTxt: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::removeServiceTxt +*/ +bool MDNSResponder::removeServiceTxt(const MDNSResponder::hMDNSService p_hService, + const char* p_pcKey) { + bool bResult = false; + + stcMDNSService* pService = _findService(p_hService); + if (pService) { + stcMDNSServiceTxt* pTxt = _findServiceTxt(pService, p_pcKey); + if (pTxt) { + bResult = _releaseServiceTxt(pService, pTxt); + } + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] removeServiceTxt: FAILED for '%s'!\n"), + (p_pcKey ? : "-")); + }); + return bResult; +} + +/* + MDNSResponder::removeServiceTxt +*/ +bool MDNSResponder::removeServiceTxt(const char* p_pcName, const char* p_pcService, + const char* p_pcProtocol, const char* p_pcKey) { + bool bResult = false; + + stcMDNSService* pService + = _findService((p_pcName ? : m_pcHostname), p_pcService, p_pcProtocol); + if (pService) { + stcMDNSServiceTxt* pTxt = _findServiceTxt(pService, p_pcKey); + if (pTxt) { + bResult = _releaseServiceTxt(pService, pTxt); + } + } + return bResult; +} + +/* + MDNSResponder::addServiceTxt (LEGACY) +*/ +bool MDNSResponder::addServiceTxt(const char* p_pcService, const char* p_pcProtocol, + const char* p_pcKey, const char* p_pcValue) { + return (0 + != _addServiceTxt(_findService(m_pcHostname, p_pcService, p_pcProtocol), p_pcKey, + p_pcValue, false)); +} + +/* + MDNSResponder::addServiceTxt (LEGACY) +*/ +bool MDNSResponder::addServiceTxt(const String& p_strService, const String& p_strProtocol, + const String& p_strKey, const String& p_strValue) { + return (0 + != _addServiceTxt( + _findService(m_pcHostname, p_strService.c_str(), p_strProtocol.c_str()), + p_strKey.c_str(), p_strValue.c_str(), false)); +} + +/* + MDNSResponder::setDynamicServiceTxtCallback (global) + + Set a global callback for dynamic service TXT items. The callback is called, whenever + service TXT items are needed. + +*/ +bool MDNSResponder::setDynamicServiceTxtCallback( + MDNSResponder::MDNSDynamicServiceTxtCallbackFunc p_fnCallback) { + m_fnServiceTxtCallback = p_fnCallback; + + return true; +} + +/* + MDNSResponder::setDynamicServiceTxtCallback (service specific) + + Set a service specific callback for dynamic service TXT items. The callback is called, + whenever service TXT items are needed for the given service. + +*/ +bool MDNSResponder::setDynamicServiceTxtCallback( + MDNSResponder::hMDNSService p_hService, + MDNSResponder::MDNSDynamicServiceTxtCallbackFunc p_fnCallback) { + bool bResult = false; + + stcMDNSService* pService = _findService(p_hService); + if (pService) { + pService->m_fnTxtCallback = p_fnCallback; + + bResult = true; + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] setDynamicServiceTxtCallback: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::addDynamicServiceTxt +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addDynamicServiceTxt(MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + const char* p_pcValue) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] addDynamicServiceTxt + // (%s=%s)\n"), p_pcKey, p_pcValue);); + + hMDNSTxt hTxt = 0; + + stcMDNSService* pService = _findService(p_hService); + if (pService) { + hTxt = _addServiceTxt(pService, p_pcKey, p_pcValue, true); + } + DEBUG_EX_ERR(if (!hTxt) { + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] addDynamicServiceTxt: FAILED for '%s=%s'!\n"), + (p_pcKey ? : "-"), (p_pcValue ? : "-")); + }); + return hTxt; +} + +/* + MDNSResponder::addDynamicServiceTxt (uint32_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addDynamicServiceTxt(MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + uint32_t p_u32Value) { + char acBuffer[32]; + *acBuffer = 0; + sprintf(acBuffer, "%u", (unsigned int)p_u32Value); + + return addDynamicServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addDynamicServiceTxt (uint16_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addDynamicServiceTxt(MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + uint16_t p_u16Value) { + char acBuffer[16]; + *acBuffer = 0; + sprintf(acBuffer, "%hu", p_u16Value); + + return addDynamicServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addDynamicServiceTxt (uint8_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addDynamicServiceTxt(MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + uint8_t p_u8Value) { + char acBuffer[8]; + *acBuffer = 0; + sprintf(acBuffer, "%hhu", p_u8Value); + + return addDynamicServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addDynamicServiceTxt (int32_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addDynamicServiceTxt(MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + int32_t p_i32Value) { + char acBuffer[32]; + *acBuffer = 0; + sprintf(acBuffer, "%i", (int)p_i32Value); + + return addDynamicServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addDynamicServiceTxt (int16_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addDynamicServiceTxt(MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + int16_t p_i16Value) { + char acBuffer[16]; + *acBuffer = 0; + sprintf(acBuffer, "%hi", p_i16Value); + + return addDynamicServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/* + MDNSResponder::addDynamicServiceTxt (int8_t) +*/ +MDNSResponder::hMDNSTxt +MDNSResponder::addDynamicServiceTxt(MDNSResponder::hMDNSService p_hService, const char* p_pcKey, + int8_t p_i8Value) { + char acBuffer[8]; + *acBuffer = 0; + sprintf(acBuffer, "%hhi", p_i8Value); + + return addDynamicServiceTxt(p_hService, p_pcKey, acBuffer); +} + +/** + STATIC SERVICE QUERY (LEGACY) +*/ + +/* + MDNSResponder::queryService + + Perform a (blocking) static service query. + The arrived answers can be queried by calling: + - answerHostname (or 'hostname') + - answerIP (or 'IP') + - answerPort (or 'port') + +*/ +uint32_t +MDNSResponder::queryService(const char* p_pcService, const char* p_pcProtocol, + const uint16_t p_u16Timeout /*= MDNS_QUERYSERVICES_WAIT_TIME*/) { + if (0 == m_pUDPContext) { + // safeguard against misuse + return 0; + } + + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] queryService '%s.%s'\n"), + p_pcService, p_pcProtocol);); + + uint32_t u32Result = 0; + + stcMDNSServiceQuery* pServiceQuery = 0; + if ((p_pcService) && (strlen(p_pcService)) && (p_pcProtocol) && (strlen(p_pcProtocol)) + && (p_u16Timeout) && (_removeLegacyServiceQuery()) + && ((pServiceQuery = _allocServiceQuery())) + && (_buildDomainForService(p_pcService, p_pcProtocol, + pServiceQuery->m_ServiceTypeDomain))) { + pServiceQuery->m_bLegacyQuery = true; + + if (_sendMDNSServiceQuery(*pServiceQuery)) { + // Wait for answers to arrive + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] queryService: Waiting %u ms for answers...\n"), + p_u16Timeout);); + delay(p_u16Timeout); + + // All answers should have arrived by now -> stop adding new answers + pServiceQuery->m_bAwaitingAnswers = false; + u32Result = pServiceQuery->answerCount(); + } else { // FAILED to send query + _removeServiceQuery(pServiceQuery); + } + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] queryService: INVALID input data!\n"));); + } + return u32Result; +} + +/* + MDNSResponder::removeQuery + + Remove the last static service query (and all answers). + +*/ +bool MDNSResponder::removeQuery(void) { + return _removeLegacyServiceQuery(); +} + +/* + MDNSResponder::queryService (LEGACY) +*/ +uint32_t MDNSResponder::queryService(const String& p_strService, const String& p_strProtocol) { + return queryService(p_strService.c_str(), p_strProtocol.c_str()); +} + +/* + MDNSResponder::answerHostname +*/ +const char* MDNSResponder::answerHostname(const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findLegacyServiceQuery(); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + + if ((pSQAnswer) && (pSQAnswer->m_HostDomain.m_u16NameLength) + && (!pSQAnswer->m_pcHostDomain)) { + char* pcHostDomain = pSQAnswer->allocHostDomain(pSQAnswer->m_HostDomain.c_strLength()); + if (pcHostDomain) { + pSQAnswer->m_HostDomain.c_str(pcHostDomain); + } + } + return (pSQAnswer ? pSQAnswer->m_pcHostDomain : 0); +} + +#ifdef MDNS_IP4_SUPPORT +/* + MDNSResponder::answerIP +*/ +IPAddress MDNSResponder::answerIP(const uint32_t p_u32AnswerIndex) { + const stcMDNSServiceQuery* pServiceQuery = _findLegacyServiceQuery(); + const stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + const stcMDNSServiceQuery::stcAnswer::stcIP4Address* pIP4Address + = (((pSQAnswer) && (pSQAnswer->m_pIP4Addresses)) ? pSQAnswer->IP4AddressAtIndex(0) : 0); + return (pIP4Address ? pIP4Address->m_IPAddress : IPAddress()); +} +#endif + +#ifdef MDNS_IP6_SUPPORT +/* + MDNSResponder::answerIP6 +*/ +IPAddress MDNSResponder::answerIP6(const uint32_t p_u32AnswerIndex) { + const stcMDNSServiceQuery* pServiceQuery = _findLegacyServiceQuery(); + const stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + const stcMDNSServiceQuery::stcAnswer::stcIP6Address* pIP6Address + = (((pSQAnswer) && (pSQAnswer->m_pIP6Addresses)) ? pSQAnswer->IP6AddressAtIndex(0) : 0); + return (pIP6Address ? pIP6Address->m_IPAddress : IP6Address()); +} +#endif + +/* + MDNSResponder::answerPort +*/ +uint16_t MDNSResponder::answerPort(const uint32_t p_u32AnswerIndex) { + const stcMDNSServiceQuery* pServiceQuery = _findLegacyServiceQuery(); + const stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return (pSQAnswer ? pSQAnswer->m_u16Port : 0); +} + +/* + MDNSResponder::hostname (LEGACY) +*/ +String MDNSResponder::hostname(const uint32_t p_u32AnswerIndex) { + return String(answerHostname(p_u32AnswerIndex)); +} + +/* + MDNSResponder::IP (LEGACY) +*/ +IPAddress MDNSResponder::IP(const uint32_t p_u32AnswerIndex) { + return answerIP(p_u32AnswerIndex); +} + +/* + MDNSResponder::port (LEGACY) +*/ +uint16_t MDNSResponder::port(const uint32_t p_u32AnswerIndex) { + return answerPort(p_u32AnswerIndex); +} + +/** + DYNAMIC SERVICE QUERY +*/ + +/* + MDNSResponder::installServiceQuery + + Add a dynamic service query and a corresponding callback to the MDNS responder. + The callback will be called for every answer update. + The answers can also be queried by calling: + - answerServiceDomain + - answerHostDomain + - answerIP4Address/answerIP6Address + - answerPort + - answerTxts + +*/ +MDNSResponder::hMDNSServiceQuery +MDNSResponder::installServiceQuery(const char* p_pcService, const char* p_pcProtocol, + MDNSResponder::MDNSServiceQueryCallbackFunc p_fnCallback) { + hMDNSServiceQuery hResult = 0; + + stcMDNSServiceQuery* pServiceQuery = 0; + if ((p_pcService) && (strlen(p_pcService)) && (p_pcProtocol) && (strlen(p_pcProtocol)) + && (p_fnCallback) && ((pServiceQuery = _allocServiceQuery())) + && (_buildDomainForService(p_pcService, p_pcProtocol, + pServiceQuery->m_ServiceTypeDomain))) { + pServiceQuery->m_fnCallback = p_fnCallback; + pServiceQuery->m_bLegacyQuery = false; + + if (_sendMDNSServiceQuery(*pServiceQuery)) { + pServiceQuery->m_u8SentCount = 1; + pServiceQuery->m_ResendTimeout.reset(MDNS_DYNAMIC_QUERY_RESEND_DELAY); + + hResult = (hMDNSServiceQuery)pServiceQuery; + } else { + _removeServiceQuery(pServiceQuery); + } + } + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] installServiceQuery: %s for '%s.%s'!\n\n"), + (hResult ? "Succeeded" : "FAILED"), (p_pcService ? : "-"), (p_pcProtocol ? : "-"));); + DEBUG_EX_ERR(if (!hResult) { + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] installServiceQuery: FAILED for '%s.%s'!\n\n"), + (p_pcService ? : "-"), (p_pcProtocol ? : "-")); + }); + return hResult; +} + +/* + MDNSResponder::removeServiceQuery + + Remove a dynamic service query (and all collected answers) from the MDNS responder + +*/ +bool MDNSResponder::removeServiceQuery(MDNSResponder::hMDNSServiceQuery p_hServiceQuery) { + stcMDNSServiceQuery* pServiceQuery = 0; + bool bResult = (((pServiceQuery = _findServiceQuery(p_hServiceQuery))) + && (_removeServiceQuery(pServiceQuery))); + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] removeServiceQuery: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::answerCount +*/ +uint32_t MDNSResponder::answerCount(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + return (pServiceQuery ? pServiceQuery->answerCount() : 0); +} + +std::vector +MDNSResponder::answerInfo(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery) { + std::vector tempVector; + for (uint32_t i = 0; i < answerCount(p_hServiceQuery); i++) { + tempVector.emplace_back(*this, p_hServiceQuery, i); + } + return tempVector; +} + +/* + MDNSResponder::answerServiceDomain + + Returns the domain for the given service. + If not already existing, the string is allocated, filled and attached to the answer. + +*/ +const char* +MDNSResponder::answerServiceDomain(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + // Fill m_pcServiceDomain (if not already done) + if ((pSQAnswer) && (pSQAnswer->m_ServiceDomain.m_u16NameLength) + && (!pSQAnswer->m_pcServiceDomain)) { + pSQAnswer->m_pcServiceDomain + = pSQAnswer->allocServiceDomain(pSQAnswer->m_ServiceDomain.c_strLength()); + if (pSQAnswer->m_pcServiceDomain) { + pSQAnswer->m_ServiceDomain.c_str(pSQAnswer->m_pcServiceDomain); + } + } + return (pSQAnswer ? pSQAnswer->m_pcServiceDomain : 0); +} + +/* + MDNSResponder::hasAnswerHostDomain +*/ +bool MDNSResponder::hasAnswerHostDomain(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return ((pSQAnswer) + && (pSQAnswer->m_u32ContentFlags & ServiceQueryAnswerType_HostDomainAndPort)); +} + +/* + MDNSResponder::answerHostDomain + + Returns the host domain for the given service. + If not already existing, the string is allocated, filled and attached to the answer. + +*/ +const char* +MDNSResponder::answerHostDomain(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + // Fill m_pcHostDomain (if not already done) + if ((pSQAnswer) && (pSQAnswer->m_HostDomain.m_u16NameLength) + && (!pSQAnswer->m_pcHostDomain)) { + pSQAnswer->m_pcHostDomain + = pSQAnswer->allocHostDomain(pSQAnswer->m_HostDomain.c_strLength()); + if (pSQAnswer->m_pcHostDomain) { + pSQAnswer->m_HostDomain.c_str(pSQAnswer->m_pcHostDomain); + } + } + return (pSQAnswer ? pSQAnswer->m_pcHostDomain : 0); +} + +#ifdef MDNS_IP4_SUPPORT +/* + MDNSResponder::hasAnswerIP4Address +*/ +bool MDNSResponder::hasAnswerIP4Address(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return ((pSQAnswer) && (pSQAnswer->m_u32ContentFlags & ServiceQueryAnswerType_IP4Address)); +} + +/* + MDNSResponder::answerIP4AddressCount +*/ +uint32_t +MDNSResponder::answerIP4AddressCount(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return (pSQAnswer ? pSQAnswer->IP4AddressCount() : 0); +} + +/* + MDNSResponder::answerIP4Address +*/ +IPAddress +MDNSResponder::answerIP4Address(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex, + const uint32_t p_u32AddressIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + stcMDNSServiceQuery::stcAnswer::stcIP4Address* pIP4Address + = (pSQAnswer ? pSQAnswer->IP4AddressAtIndex(p_u32AddressIndex) : 0); + return (pIP4Address ? pIP4Address->m_IPAddress : IPAddress()); +} +#endif + +#ifdef MDNS_IP6_SUPPORT +/* + MDNSResponder::hasAnswerIP6Address +*/ +bool MDNSResponder::hasAnswerIP6Address(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return ((pSQAnswer) + && (pSQAnswer->m_u32ContentFlags & ServiceQueryAnswerType_HostIP6Address)); +} + +/* + MDNSResponder::answerIP6AddressCount +*/ +uint32_t +MDNSResponder::answerIP6AddressCount(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return (pSQAnswer ? pSQAnswer->IP6AddressCount() : 0); +} + +/* + MDNSResponder::answerIP6Address +*/ +IPAddress +MDNSResponder::answerIP6Address(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex, + const uint32_t p_u32AddressIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + stcMDNSServiceQuery::stcAnswer::stcIP6Address* pIP6Address + = (pSQAnswer ? pSQAnswer->IP6AddressAtIndex(p_u32AddressIndex) : 0); + return (pIP6Address ? pIP6Address->m_IPAddress : IPAddress()); +} +#endif + +/* + MDNSResponder::hasAnswerPort +*/ +bool MDNSResponder::hasAnswerPort(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return ((pSQAnswer) + && (pSQAnswer->m_u32ContentFlags & ServiceQueryAnswerType_HostDomainAndPort)); +} + +/* + MDNSResponder::answerPort +*/ +uint16_t MDNSResponder::answerPort(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return (pSQAnswer ? pSQAnswer->m_u16Port : 0); +} + +/* + MDNSResponder::hasAnswerTxts +*/ +bool MDNSResponder::hasAnswerTxts(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + return ((pSQAnswer) && (pSQAnswer->m_u32ContentFlags & ServiceQueryAnswerType_Txts)); +} + +/* + MDNSResponder::answerTxts + + Returns all TXT items for the given service as a ';'-separated string. + If not already existing; the string is allocated, filled and attached to the answer. + +*/ +const char* MDNSResponder::answerTxts(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + // Fill m_pcTxts (if not already done) + if ((pSQAnswer) && (pSQAnswer->m_Txts.m_pTxts) && (!pSQAnswer->m_pcTxts)) { + pSQAnswer->m_pcTxts = pSQAnswer->allocTxts(pSQAnswer->m_Txts.c_strLength()); + if (pSQAnswer->m_pcTxts) { + pSQAnswer->m_Txts.c_str(pSQAnswer->m_pcTxts); + } + } + return (pSQAnswer ? pSQAnswer->m_pcTxts : 0); +} + +/* + PROBING +*/ + +/* + MDNSResponder::setProbeResultCallback + + Set a global callback for probe results. The callback is called, when probing + for the host domain (or a service domain, without specific probe result callback) + fails or succeeds. + In the case of failure, the domain name should be changed via 'setHostname' or + 'setServiceName'. When succeeded, the host or service domain will be announced by the MDNS + responder. + +*/ +bool MDNSResponder::setHostProbeResultCallback(MDNSResponder::MDNSHostProbeFn p_fnCallback) { + m_HostProbeInformation.m_fnHostProbeResultCallback = p_fnCallback; + + return true; +} + +bool MDNSResponder::setHostProbeResultCallback(MDNSHostProbeFn1 pfn) { + using namespace std::placeholders; + return setHostProbeResultCallback( + [this, pfn](const char* p_pcDomainName, bool p_bProbeResult) { + pfn(*this, p_pcDomainName, p_bProbeResult); + }); +} + +/* + MDNSResponder::setServiceProbeResultCallback + + Set a service specific callback for probe results. The callback is called, when probing + for the service domain fails or succeeds. + In the case of failure, the service name should be changed via 'setServiceName'. + When succeeded, the service domain will be announced by the MDNS responder. + +*/ +bool +MDNSResponder::setServiceProbeResultCallback(const MDNSResponder::hMDNSService p_hService, + MDNSResponder::MDNSServiceProbeFn p_fnCallback) { + bool bResult = false; + + stcMDNSService* pService = _findService(p_hService); + if (pService) { + pService->m_ProbeInformation.m_fnServiceProbeResultCallback = p_fnCallback; + + bResult = true; + } + return bResult; +} + +bool +MDNSResponder::setServiceProbeResultCallback(const MDNSResponder::hMDNSService p_hService, + MDNSResponder::MDNSServiceProbeFn1 p_fnCallback) { + using namespace std::placeholders; + return setServiceProbeResultCallback( + p_hService, + [this, p_fnCallback](const char* p_pcServiceName, const hMDNSService p_hMDNSService, + bool p_bProbeResult) { + p_fnCallback(*this, p_pcServiceName, p_hMDNSService, p_bProbeResult); + }); +} + +/* + MISC +*/ + +/* + MDNSResponder::notifyAPChange + + Should be called, whenever the AP for the MDNS responder changes. + A bit of this is caught by the event callbacks installed in the constructor. + +*/ +bool MDNSResponder::notifyAPChange(void) { + return _restart(); +} + +/* + MDNSResponder::update + + Should be called in every 'loop'. + +*/ +bool MDNSResponder::update(void) { + return _process(true); +} + +/* + MDNSResponder::announce + + Should be called, if the 'configuration' changes. Mainly this will be changes in the TXT + items... +*/ +bool MDNSResponder::announce(void) { + return (_announce(true, true)); +} + +/* + MDNSResponder::enableArduino + + Enable the OTA update service. + +*/ +MDNSResponder::hMDNSService MDNSResponder::enableArduino(uint16_t p_u16Port, + bool p_bAuthUpload /*= false*/) { + hMDNSService hService = addService(0, "arduino", "tcp", p_u16Port); + if (hService) { + if ((!addServiceTxt(hService, "tcp_check", "no")) + || (!addServiceTxt(hService, "ssh_upload", "no")) + || (!addServiceTxt(hService, "board", ARDUINO_VARIANT)) + || (!addServiceTxt(hService, "auth_upload", (p_bAuthUpload) ? "yes" : "no"))) { + removeService(hService); + hService = 0; + } + } + return hService; +} + +/* + + MULTICAST GROUPS + +*/ + +/* + MDNSResponder::_joinMulticastGroups +*/ +bool MDNSResponder::_joinMulticastGroups(void) { + bool bResult = false; + + // Join multicast group(s) + for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next) { + if (netif_is_up(pNetIf)) { +#ifdef MDNS_IP4_SUPPORT + ip_addr_t multicast_addr_V4 = DNS_MQUERY_IPV4_GROUP_INIT; + if (!(pNetIf->flags & NETIF_FLAG_IGMP)) { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR( + "[MDNSResponder] _createHost: Setting flag: flags & NETIF_FLAG_IGMP\n"));); + pNetIf->flags |= NETIF_FLAG_IGMP; + + if (ERR_OK != igmp_start(pNetIf)) { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _createHost: igmp_start FAILED!\n"));); + } + } + + if ((ERR_OK == igmp_joingroup_netif(pNetIf, ip_2_ip4(&multicast_addr_V4)))) { + bResult = true; + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _createHost: igmp_joingroup_netif(" NETIFID_STR + ": %s) FAILED!\n"), + NETIFID_VAL(pNetIf), IPAddress(multicast_addr_V4).toString().c_str());); + } +#endif + +#ifdef MDNS_IPV6_SUPPORT + ip_addr_t multicast_addr_V6 = DNS_MQUERY_IPV6_GROUP_INIT; + bResult + = ((bResult) + && (ERR_OK == mld6_joingroup_netif(pNetIf, ip_2_ip6(&multicast_addr_V6)))); + DEBUG_EX_ERR_IF( + !bResult, + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _createHost: mld6_joingroup_netif (" NETIFID_STR + ") FAILED!\n"), + NETIFID_VAL(pNetIf))); +#endif + } + } + return bResult; +} + +/* + clsLEAmDNS2_Host::_leaveMulticastGroups +*/ +bool MDNSResponder::_leaveMulticastGroups() { + bool bResult = false; + + for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next) { + if (netif_is_up(pNetIf)) { + bResult = true; + + // Leave multicast group(s) +#ifdef MDNS_IP4_SUPPORT + ip_addr_t multicast_addr_V4 = DNS_MQUERY_IPV4_GROUP_INIT; + if (ERR_OK != igmp_leavegroup_netif(pNetIf, ip_2_ip4(&multicast_addr_V4))) { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("\n"));); + } +#endif +#ifdef MDNS_IPV6_SUPPORT + ip_addr_t multicast_addr_V6 = DNS_MQUERY_IPV6_GROUP_INIT; + if (ERR_OK + != mld6_leavegroup_netif( + pNetIf, ip_2_ip6(&multicast_addr_V6) /*&(multicast_addr_V6.u_addr.ip6)*/)) { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("\n"));); + } +#endif + } + } + return bResult; +} + +} // namespace MDNSImplementation + +} // namespace esp8266 diff --git a/libraries/LEAmDNS/src/LEAmDNS.h b/libraries/LEAmDNS/src/LEAmDNS.h new file mode 100644 index 00000000..a837f360 --- /dev/null +++ b/libraries/LEAmDNS/src/LEAmDNS.h @@ -0,0 +1,1350 @@ +/* + LEAmDNS.h + (c) 2018, LaborEtArs + + Version 0.9 beta + + Some notes (from LaborEtArs, 2018): + Essentially, this is an rewrite of the original EPS8266 Multicast DNS code (ESP8266mDNS). + The target of this rewrite was to keep the existing interface as stable as possible while + adding and extending the supported set of mDNS features. + A lot of the additions were basically taken from Erik Ekman's lwIP mdns app code. + + Supported mDNS features (in some cases somewhat limited): + - Presenting a DNS-SD service to interested observers, eg. a http server by presenting + _http._tcp service + - Support for multi-level compressed names in input; in output only a very simple one-leven + full-name compression is implemented + - Probing host and service domains for uniqueness in the local network + - Tiebreaking while probing is supported in a very minimalistic way (the 'higher' IP address + wins the tiebreak) + - Announcing available services after successful probing + - Using fixed service TXT items or + - Using dynamic service TXT items for presented services (via callback) + - Remove services (and un-announcing them to the observers by sending goodbye-messages) + - Static queries for DNS-SD services (creating a fixed answer set after a certain timeout + period) + - Dynamic queries for DNS-SD services with cached and updated answers and user notifications + + + Usage: + In most cases, this implementation should work as a 'drop-in' replacement for the original + ESP8266 Multicast DNS code. Adjustments to the existing code would only be needed, if some + of the new features should be used. + + For presenting services: + In 'setup()': + Install a callback for the probing of host (and service) domains via + 'MDNS.setProbeResultCallback(probeResultCallback, &userData);' Register DNS-SD services with + 'MDNSResponder::hMDNSService hService = MDNS.addService("MyESP", "http", "tcp", 5000);' (Install + additional callbacks for the probing of these service domains via + 'MDNS.setServiceProbeResultCallback(hService, probeResultCallback, &userData);') Add service TXT + items with 'MDNS.addServiceTxt(hService, "c#", "1");' or by installing a service TXT callback + using 'MDNS.setDynamicServiceTxtCallback(dynamicServiceTxtCallback, &userData);' or service + specific 'MDNS.setDynamicServiceTxtCallback(hService, dynamicServiceTxtCallback, &userData);' + Call MDNS.begin("MyHostname"); + + In 'probeResultCallback(MDNSResponder* p_MDNSResponder, const char* p_pcDomain, + MDNSResponder:hMDNSService p_hService, bool p_bProbeResult, void* p_pUserdata)': Check the probe + result and update the host or service domain name if the probe failed + + In 'dynamicServiceTxtCallback(MDNSResponder* p_MDNSResponder, const hMDNSService p_hService, + void* p_pUserdata)': Add dynamic TXT items by calling 'MDNS.addDynamicServiceTxt(p_hService, + "c#", "1");' + + In loop(): + Call 'MDNS.update();' + + + For querying services: + Static: + Call 'uint32_t u32AnswerCount = MDNS.queryService("http", "tcp");' + Iterate answers by: 'for (uint32_t u=0; u // for UdpContext.h +#include "WiFiUdp.h" +#include "lwip/udp.h" +#include "debug_internal.h" +#include "include/UdpContext.h" +#include +#include +#include +#include +#include "ESP8266WiFi.h" + +namespace esp8266 { + +/** + LEAmDNS +*/ +namespace MDNSImplementation { + +// this should be defined at build time +#ifndef ARDUINO_BOARD +#define ARDUINO_BOARD "generic" +#endif + +#define MDNS_IP4_SUPPORT +#if LWIP_IPV6 +//#define MDNS_IP6_SUPPORT +#endif + +#ifdef MDNS_IP4_SUPPORT +#define MDNS_IP4_SIZE 4 +#endif +#ifdef MDNS_IP6_SUPPORT +#define MDNS_IP6_SIZE 16 +#endif +/* + Maximum length for all service txts for one service +*/ +#define MDNS_SERVICE_TXT_MAXLENGTH 1300 +/* + Maximum length for a full domain name eg. MyESP._http._tcp.local +*/ +#define MDNS_DOMAIN_MAXLENGTH 256 +/* + Maximum length of on label in a domain name (length info fits into 6 bits) +*/ +#define MDNS_DOMAIN_LABEL_MAXLENGTH 63 +/* + Maximum length of a service name eg. http +*/ +#define MDNS_SERVICE_NAME_LENGTH 15 +/* + Maximum length of a service protocol name eg. tcp +*/ +#define MDNS_SERVICE_PROTOCOL_LENGTH 3 +/* + Default timeout for static service queries +*/ +#define MDNS_QUERYSERVICES_WAIT_TIME 1000 + +/* + Timeout for udpContext->sendtimeout() +*/ +#define MDNS_UDPCONTEXT_TIMEOUT 50 + +/** + MDNSResponder +*/ +class MDNSResponder { +public: + /* INTERFACE */ + + MDNSResponder(void); + virtual ~MDNSResponder(void); + + // Start the MDNS responder by setting the default hostname + // Later call MDNS::update() in every 'loop' to run the process loop + // (probing, announcing, responding, ...) + // if interfaceAddress is not specified, default interface is STA, or AP when STA is not set + bool begin(const char* p_pcHostname, const IPAddress& p_IPAddress = INADDR_ANY, + uint32_t p_u32TTL = 120 /*ignored*/); + bool begin(const String& p_strHostname, const IPAddress& p_IPAddress = INADDR_ANY, + uint32_t p_u32TTL = 120 /*ignored*/) { + return begin(p_strHostname.c_str(), p_IPAddress, p_u32TTL); + } + bool _joinMulticastGroups(void); + bool _leaveMulticastGroups(void); + + // Finish MDNS processing + bool close(void); + // for esp32 compatibility + bool end(void); + // Change hostname (probing is restarted) + bool setHostname(const char* p_pcHostname); + // for compatibility... + bool setHostname(const String& p_strHostname); + + bool isRunning(void) { + return (m_pUDPContext != 0); + } + + /** + hMDNSService (opaque handle to access the service) + */ + typedef const void* hMDNSService; + + // Add a new service to the MDNS responder. If no name (instance name) is given (p_pcName = + // 0) the current hostname is used. If the hostname is changed later, the instance names for + // these 'auto-named' services are changed to the new name also (and probing is restarted). + // The usual '_' before p_pcService (eg. http) and protocol (eg. tcp) may be given. + hMDNSService addService(const char* p_pcName, const char* p_pcService, + const char* p_pcProtocol, uint16_t p_u16Port); + // Removes a service from the MDNS responder + bool removeService(const hMDNSService p_hService); + bool removeService(const char* p_pcInstanceName, const char* p_pcServiceName, + const char* p_pcProtocol); + // for compatibility... + bool addService(const String& p_strServiceName, const String& p_strProtocol, + uint16_t p_u16Port); + + // Change the services instance name (and restart probing). + bool setServiceName(const hMDNSService p_hService, const char* p_pcInstanceName); + // for compatibility + // Warning: this has the side effect of changing the hostname. + // TODO: implement instancename different from hostname + void setInstanceName(const char* p_pcHostname) { + setHostname(p_pcHostname); + } + // for esp32 compatibility + void setInstanceName(const String& s_pcHostname) { + setInstanceName(s_pcHostname.c_str()); + } + + /** + hMDNSTxt (opaque handle to access the TXT items) + */ + typedef void* hMDNSTxt; + + // Add a (static) MDNS TXT item ('key' = 'value') to the service + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, + const char* p_pcValue); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, + uint32_t p_u32Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, + uint16_t p_u16Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, + uint8_t p_u8Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, + int32_t p_i32Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, + int16_t p_i16Value); + hMDNSTxt addServiceTxt(const hMDNSService p_hService, const char* p_pcKey, + int8_t p_i8Value); + + // Remove an existing (static) MDNS TXT item from the service + bool removeServiceTxt(const hMDNSService p_hService, const hMDNSTxt p_hTxt); + bool removeServiceTxt(const hMDNSService p_hService, const char* p_pcKey); + bool removeServiceTxt(const char* p_pcinstanceName, const char* p_pcServiceName, + const char* p_pcProtocol, const char* p_pcKey); + // for compatibility... + bool addServiceTxt(const char* p_pcService, const char* p_pcProtocol, const char* p_pcKey, + const char* p_pcValue); + bool addServiceTxt(const String& p_strService, const String& p_strProtocol, + const String& p_strKey, const String& p_strValue); + + /** + MDNSDynamicServiceTxtCallbackFn + Callback function for dynamic MDNS TXT items + */ + + typedef std::function + MDNSDynamicServiceTxtCallbackFunc; + + // Set a global callback for dynamic MDNS TXT items. The callback function is called + // every time, a TXT item is needed for one of the installed services. + bool setDynamicServiceTxtCallback(MDNSDynamicServiceTxtCallbackFunc p_fnCallback); + // Set a service specific callback for dynamic MDNS TXT items. The callback function + // is called every time, a TXT item is needed for the given service. + bool setDynamicServiceTxtCallback(const hMDNSService p_hService, + MDNSDynamicServiceTxtCallbackFunc p_fnCallback); + + // Add a (dynamic) MDNS TXT item ('key' = 'value') to the service + // Dynamic TXT items are removed right after one-time use. So they need to be added + // every time the value s needed (via callback). + hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey, + const char* p_pcValue); + hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey, + uint32_t p_u32Value); + hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey, + uint16_t p_u16Value); + hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey, + uint8_t p_u8Value); + hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey, + int32_t p_i32Value); + hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey, + int16_t p_i16Value); + hMDNSTxt addDynamicServiceTxt(hMDNSService p_hService, const char* p_pcKey, + int8_t p_i8Value); + + // Perform a (static) service query. The function returns after p_u16Timeout milliseconds + // The answers (the number of received answers is returned) can be retrieved by calling + // - answerHostname (or hostname) + // - answerIP (or IP) + // - answerPort (or port) + uint32_t queryService(const char* p_pcService, const char* p_pcProtocol, + const uint16_t p_u16Timeout = MDNS_QUERYSERVICES_WAIT_TIME); + bool removeQuery(void); + // for compatibility... + uint32_t queryService(const String& p_strService, const String& p_strProtocol); + + const char* answerHostname(const uint32_t p_u32AnswerIndex); + IPAddress answerIP(const uint32_t p_u32AnswerIndex); + uint16_t answerPort(const uint32_t p_u32AnswerIndex); + // for compatibility... + String hostname(const uint32_t p_u32AnswerIndex); + IPAddress IP(const uint32_t p_u32AnswerIndex); + uint16_t port(const uint32_t p_u32AnswerIndex); + + /** + hMDNSServiceQuery (opaque handle to access dynamic service queries) + */ + typedef const void* hMDNSServiceQuery; + + /** + enuServiceQueryAnswerType + */ + typedef enum _enuServiceQueryAnswerType { + ServiceQueryAnswerType_ServiceDomain = (1 << 0), // Service instance name + ServiceQueryAnswerType_HostDomainAndPort = (1 << 1), // Host domain and service port + ServiceQueryAnswerType_Txts = (1 << 2), // TXT items +#ifdef MDNS_IP4_SUPPORT + ServiceQueryAnswerType_IP4Address = (1 << 3), // IP4 address +#endif +#ifdef MDNS_IP6_SUPPORT + ServiceQueryAnswerType_IP6Address = (1 << 4), // IP6 address +#endif + } enuServiceQueryAnswerType; + + enum class AnswerType : uint32_t { + Unknown = 0, + ServiceDomain = ServiceQueryAnswerType_ServiceDomain, + HostDomainAndPort = ServiceQueryAnswerType_HostDomainAndPort, + Txt = ServiceQueryAnswerType_Txts, +#ifdef MDNS_IP4_SUPPORT + IP4Address = ServiceQueryAnswerType_IP4Address, +#endif +#ifdef MDNS_IP6_SUPPORT + IP6Address = ServiceQueryAnswerType_IP6Address, +#endif + }; + + /** + MDNSServiceQueryCallbackFn + Callback function for received answers for dynamic service queries + */ + struct MDNSServiceInfo; // forward declaration + typedef std::function + MDNSServiceQueryCallbackFunc; + + // Install a dynamic service query. For every received answer (part) the given callback + // function is called. The query will be updated every time, the TTL for an answer + // has timed-out. + // The answers can also be retrieved by calling + // - answerCount + // - answerServiceDomain + // - hasAnswerHostDomain/answerHostDomain + // - hasAnswerIP4Address/answerIP4Address + // - hasAnswerIP6Address/answerIP6Address + // - hasAnswerPort/answerPort + // - hasAnswerTxts/answerTxts + hMDNSServiceQuery installServiceQuery(const char* p_pcService, const char* p_pcProtocol, + MDNSServiceQueryCallbackFunc p_fnCallback); + // Remove a dynamic service query + bool removeServiceQuery(hMDNSServiceQuery p_hServiceQuery); + + uint32_t answerCount(const hMDNSServiceQuery p_hServiceQuery); + std::vector + answerInfo(const MDNSResponder::hMDNSServiceQuery p_hServiceQuery); + + const char* answerServiceDomain(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + bool hasAnswerHostDomain(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + const char* answerHostDomain(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); +#ifdef MDNS_IP4_SUPPORT + bool hasAnswerIP4Address(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + uint32_t answerIP4AddressCount(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + IPAddress answerIP4Address(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex, + const uint32_t p_u32AddressIndex); +#endif +#ifdef MDNS_IP6_SUPPORT + bool hasAnswerIP6Address(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + uint32_t answerIP6AddressCount(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + IPAddress answerIP6Address(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex, + const uint32_t p_u32AddressIndex); +#endif + bool hasAnswerPort(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + uint16_t answerPort(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + bool hasAnswerTxts(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + // Get the TXT items as a ';'-separated string + const char* answerTxts(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + + /** + MDNSProbeResultCallbackFn + Callback function for (host and service domain) probe results + */ + typedef std::function + MDNSHostProbeFn; + + typedef std::function + MDNSHostProbeFn1; + + typedef std::function + MDNSServiceProbeFn; + + typedef std::function + MDNSServiceProbeFn1; + + // Set a global callback function for host and service probe results + // The callback function is called, when the probing for the host domain + // (or a service domain, which hasn't got a service specific callback) + // Succeeds or fails. + // In case of failure, the failed domain name should be changed. + bool setHostProbeResultCallback(MDNSHostProbeFn p_fnCallback); + bool setHostProbeResultCallback(MDNSHostProbeFn1 p_fnCallback); + + // Set a service specific probe result callback + bool setServiceProbeResultCallback(const MDNSResponder::hMDNSService p_hService, + MDNSServiceProbeFn p_fnCallback); + bool setServiceProbeResultCallback(const MDNSResponder::hMDNSService p_hService, + MDNSServiceProbeFn1 p_fnCallback); + + // Application should call this whenever AP is configured/disabled + bool notifyAPChange(void); + + // 'update' should be called in every 'loop' to run the MDNS processing + bool update(void); + + // 'announce' can be called every time, the configuration of some service + // changes. Mainly, this would be changed content of TXT items. + bool announce(void); + + // Enable OTA update + hMDNSService enableArduino(uint16_t p_u16Port, bool p_bAuthUpload = false); + + // Domain name helper + static bool indexDomain(char*& p_rpcDomain, const char* p_pcDivider = "-", + const char* p_pcDefaultDomain = 0); + + // Start background update operation + void enableBackgroundMode(uint32_t ms = 100); + + static bool _backgroundCB(repeating_timer *cb) { + MDNSResponder *t = (MDNSResponder*)cb->user_data; + return t->_backgroundCallback(); + } + repeating_timer_t _backgroundTimer; + bool _backgroundCallback(); + + /** STRUCTS **/ + +public: + /** + MDNSServiceInfo, used in application callbacks + */ + struct MDNSServiceInfo { + MDNSServiceInfo(MDNSResponder& p_pM, MDNSResponder::hMDNSServiceQuery p_hS, + uint32_t p_u32A) : + p_pMDNSResponder(p_pM), + p_hServiceQuery(p_hS), p_u32AnswerIndex(p_u32A) {}; + struct CompareKey { + bool operator()(char const* a, char const* b) const { + return strcmp(a, b) < 0; + } + }; + using KeyValueMap = std::map; + + protected: + MDNSResponder& p_pMDNSResponder; + MDNSResponder::hMDNSServiceQuery p_hServiceQuery; + uint32_t p_u32AnswerIndex; + KeyValueMap keyValueMap; + + public: + const char* serviceDomain() { + return p_pMDNSResponder.answerServiceDomain(p_hServiceQuery, p_u32AnswerIndex); + }; + bool hostDomainAvailable() { + return (p_pMDNSResponder.hasAnswerHostDomain(p_hServiceQuery, p_u32AnswerIndex)); + } + const char* hostDomain() { + return (hostDomainAvailable()) + ? p_pMDNSResponder.answerHostDomain(p_hServiceQuery, p_u32AnswerIndex) + : nullptr; + }; + bool hostPortAvailable() { + return (p_pMDNSResponder.hasAnswerPort(p_hServiceQuery, p_u32AnswerIndex)); + } + uint16_t hostPort() { + return (hostPortAvailable()) + ? p_pMDNSResponder.answerPort(p_hServiceQuery, p_u32AnswerIndex) + : 0; + }; + bool IP4AddressAvailable() { + return (p_pMDNSResponder.hasAnswerIP4Address(p_hServiceQuery, p_u32AnswerIndex)); + } + std::vector IP4Adresses() { + std::vector internalIP; + if (IP4AddressAvailable()) { + uint16_t cntIP4Adress + = p_pMDNSResponder.answerIP4AddressCount(p_hServiceQuery, p_u32AnswerIndex); + for (uint32_t u2 = 0; u2 < cntIP4Adress; ++u2) { + internalIP.emplace_back(p_pMDNSResponder.answerIP4Address( + p_hServiceQuery, p_u32AnswerIndex, u2)); + } + } + return internalIP; + }; + bool txtAvailable() { + return (p_pMDNSResponder.hasAnswerTxts(p_hServiceQuery, p_u32AnswerIndex)); + } + const char* strKeyValue() { + return (txtAvailable()) + ? p_pMDNSResponder.answerTxts(p_hServiceQuery, p_u32AnswerIndex) + : nullptr; + }; + const KeyValueMap& keyValues() { + if (txtAvailable() && keyValueMap.size() == 0) { + for (auto kv + = p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex); + kv != nullptr; kv = kv->m_pNext) { + keyValueMap.emplace( + std::pair(kv->m_pcKey, kv->m_pcValue)); + } + } + return keyValueMap; + } + const char* value(const char* key) { + char* result = nullptr; + + for (stcMDNSServiceTxt * pTxt + = p_pMDNSResponder._answerKeyValue(p_hServiceQuery, p_u32AnswerIndex); + pTxt; pTxt = pTxt->m_pNext) { + if ((key) && (0 == strcmp(pTxt->m_pcKey, key))) { + result = pTxt->m_pcValue; + break; + } + } + return result; + } + }; + +protected: + /** + stcMDNSServiceTxt + */ + struct stcMDNSServiceTxt { + stcMDNSServiceTxt* m_pNext; + char* m_pcKey; + char* m_pcValue; + bool m_bTemp; + + stcMDNSServiceTxt(const char* p_pcKey = 0, const char* p_pcValue = 0, + bool p_bTemp = false); + stcMDNSServiceTxt(const stcMDNSServiceTxt& p_Other); + ~stcMDNSServiceTxt(void); + + stcMDNSServiceTxt& operator=(const stcMDNSServiceTxt& p_Other); + bool clear(void); + + char* allocKey(size_t p_stLength); + bool setKey(const char* p_pcKey, size_t p_stLength); + bool setKey(const char* p_pcKey); + bool releaseKey(void); + + char* allocValue(size_t p_stLength); + bool setValue(const char* p_pcValue, size_t p_stLength); + bool setValue(const char* p_pcValue); + bool releaseValue(void); + + bool set(const char* p_pcKey, const char* p_pcValue, bool p_bTemp = false); + + bool update(const char* p_pcValue); + + size_t length(void) const; + }; + + /** + stcMDNSTxts + */ + struct stcMDNSServiceTxts { + stcMDNSServiceTxt* m_pTxts; + + stcMDNSServiceTxts(void); + stcMDNSServiceTxts(const stcMDNSServiceTxts& p_Other); + ~stcMDNSServiceTxts(void); + + stcMDNSServiceTxts& operator=(const stcMDNSServiceTxts& p_Other); + + bool clear(void); + + bool add(stcMDNSServiceTxt* p_pTxt); + bool remove(stcMDNSServiceTxt* p_pTxt); + + bool removeTempTxts(void); + + stcMDNSServiceTxt* find(const char* p_pcKey); + const stcMDNSServiceTxt* find(const char* p_pcKey) const; + stcMDNSServiceTxt* find(const stcMDNSServiceTxt* p_pTxt); + + uint16_t length(void) const; + + size_t c_strLength(void) const; + bool c_str(char* p_pcBuffer); + + size_t bufferLength(void) const; + bool buffer(char* p_pcBuffer); + + bool compare(const stcMDNSServiceTxts& p_Other) const; + bool operator==(const stcMDNSServiceTxts& p_Other) const; + bool operator!=(const stcMDNSServiceTxts& p_Other) const; + }; + + /** + enuContentFlags + */ + typedef enum _enuContentFlags { + // Host + ContentFlag_A = 0x01, + ContentFlag_PTR_IP4 = 0x02, + ContentFlag_PTR_IP6 = 0x04, + ContentFlag_AAAA = 0x08, + // Service + ContentFlag_PTR_TYPE = 0x10, + ContentFlag_PTR_NAME = 0x20, + ContentFlag_TXT = 0x40, + ContentFlag_SRV = 0x80, + } enuContentFlags; + + /** + stcMDNS_MsgHeader + */ + struct stcMDNS_MsgHeader { + uint16_t m_u16ID; // Identifier + bool m_1bQR : 1; // Query/Response flag + unsigned char m_4bOpcode : 4; // Operation code + bool m_1bAA : 1; // Authoritative Answer flag + bool m_1bTC : 1; // Truncation flag + bool m_1bRD : 1; // Recursion desired + bool m_1bRA : 1; // Recursion available + unsigned char m_3bZ : 3; // Zero + unsigned char m_4bRCode : 4; // Response code + uint16_t m_u16QDCount; // Question count + uint16_t m_u16ANCount; // Answer count + uint16_t m_u16NSCount; // Authority Record count + uint16_t m_u16ARCount; // Additional Record count + + stcMDNS_MsgHeader(uint16_t p_u16ID = 0, bool p_bQR = false, + unsigned char p_ucOpcode = 0, bool p_bAA = false, bool p_bTC = false, + bool p_bRD = false, bool p_bRA = false, unsigned char p_ucRCode = 0, + uint16_t p_u16QDCount = 0, uint16_t p_u16ANCount = 0, + uint16_t p_u16NSCount = 0, uint16_t p_u16ARCount = 0); + }; + + /** + stcMDNS_RRDomain + */ + struct stcMDNS_RRDomain { + char m_acName[MDNS_DOMAIN_MAXLENGTH]; // Encoded domain name + uint16_t m_u16NameLength; // Length (incl. '\0') + + stcMDNS_RRDomain(void); + stcMDNS_RRDomain(const stcMDNS_RRDomain& p_Other); + + stcMDNS_RRDomain& operator=(const stcMDNS_RRDomain& p_Other); + + bool clear(void); + + bool addLabel(const char* p_pcLabel, bool p_bPrependUnderline = false); + + bool compare(const stcMDNS_RRDomain& p_Other) const; + bool operator==(const stcMDNS_RRDomain& p_Other) const; + bool operator!=(const stcMDNS_RRDomain& p_Other) const; + bool operator>(const stcMDNS_RRDomain& p_Other) const; + + size_t c_strLength(void) const; + bool c_str(char* p_pcBuffer); + }; + + /** + stcMDNS_RRAttributes + */ + struct stcMDNS_RRAttributes { + uint16_t m_u16Type; // Type + uint16_t m_u16Class; // Class, nearly always 'IN' + + stcMDNS_RRAttributes(uint16_t p_u16Type = 0, + uint16_t p_u16Class = 1 /*DNS_RRCLASS_IN Internet*/); + stcMDNS_RRAttributes(const stcMDNS_RRAttributes& p_Other); + + stcMDNS_RRAttributes& operator=(const stcMDNS_RRAttributes& p_Other); + }; + + /** + stcMDNS_RRHeader + */ + struct stcMDNS_RRHeader { + stcMDNS_RRDomain m_Domain; + stcMDNS_RRAttributes m_Attributes; + + stcMDNS_RRHeader(void); + stcMDNS_RRHeader(const stcMDNS_RRHeader& p_Other); + + stcMDNS_RRHeader& operator=(const stcMDNS_RRHeader& p_Other); + + bool clear(void); + }; + + /** + stcMDNS_RRQuestion + */ + struct stcMDNS_RRQuestion { + stcMDNS_RRQuestion* m_pNext; + stcMDNS_RRHeader m_Header; + bool m_bUnicast; // Unicast reply requested + + stcMDNS_RRQuestion(void); + }; + + /** + enuAnswerType + */ + typedef enum _enuAnswerType { + AnswerType_A, + AnswerType_PTR, + AnswerType_TXT, + AnswerType_AAAA, + AnswerType_SRV, + AnswerType_Generic + } enuAnswerType; + + /** + stcMDNS_RRAnswer + */ + struct stcMDNS_RRAnswer { + stcMDNS_RRAnswer* m_pNext; + const enuAnswerType m_AnswerType; + stcMDNS_RRHeader m_Header; + bool m_bCacheFlush; // Cache flush command bit + uint32_t m_u32TTL; // Validity time in seconds + + virtual ~stcMDNS_RRAnswer(void); + + enuAnswerType answerType(void) const; + + bool clear(void); + + protected: + stcMDNS_RRAnswer(enuAnswerType p_AnswerType, const stcMDNS_RRHeader& p_Header, + uint32_t p_u32TTL); + }; + +#ifdef MDNS_IP4_SUPPORT + /** + stcMDNS_RRAnswerA + */ + struct stcMDNS_RRAnswerA: public stcMDNS_RRAnswer { + IPAddress m_IPAddress; + + stcMDNS_RRAnswerA(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL); + ~stcMDNS_RRAnswerA(void); + + bool clear(void); + }; +#endif + + /** + stcMDNS_RRAnswerPTR + */ + struct stcMDNS_RRAnswerPTR: public stcMDNS_RRAnswer { + stcMDNS_RRDomain m_PTRDomain; + + stcMDNS_RRAnswerPTR(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL); + ~stcMDNS_RRAnswerPTR(void); + + bool clear(void); + }; + + /** + stcMDNS_RRAnswerTXT + */ + struct stcMDNS_RRAnswerTXT: public stcMDNS_RRAnswer { + stcMDNSServiceTxts m_Txts; + + stcMDNS_RRAnswerTXT(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL); + ~stcMDNS_RRAnswerTXT(void); + + bool clear(void); + }; + +#ifdef MDNS_IP6_SUPPORT + /** + stcMDNS_RRAnswerAAAA + */ + struct stcMDNS_RRAnswerAAAA: public stcMDNS_RRAnswer { + // TODO: IP6Address m_IPAddress; + + stcMDNS_RRAnswerAAAA(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL); + ~stcMDNS_RRAnswerAAAA(void); + + bool clear(void); + }; +#endif + + /** + stcMDNS_RRAnswerSRV + */ + struct stcMDNS_RRAnswerSRV: public stcMDNS_RRAnswer { + uint16_t m_u16Priority; + uint16_t m_u16Weight; + uint16_t m_u16Port; + stcMDNS_RRDomain m_SRVDomain; + + stcMDNS_RRAnswerSRV(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL); + ~stcMDNS_RRAnswerSRV(void); + + bool clear(void); + }; + + /** + stcMDNS_RRAnswerGeneric + */ + struct stcMDNS_RRAnswerGeneric: public stcMDNS_RRAnswer { + uint16_t m_u16RDLength; // Length of variable answer + uint8_t* m_pu8RDData; // Offset of start of variable answer in packet + + stcMDNS_RRAnswerGeneric(const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL); + ~stcMDNS_RRAnswerGeneric(void); + + bool clear(void); + }; + + /** + enuProbingStatus + */ + typedef enum _enuProbingStatus { + ProbingStatus_WaitingForData, + ProbingStatus_ReadyToStart, + ProbingStatus_InProgress, + ProbingStatus_Done + } enuProbingStatus; + + /** + stcProbeInformation + */ + struct stcProbeInformation { + enuProbingStatus m_ProbingStatus; + uint8_t m_u8SentCount; // Used for probes and announcements + esp8266::polledTimeout::oneShotMs m_Timeout; // Used for probes and announcements + // clsMDNSTimeFlag m_TimeFlag; // Used for probes and + // announcements + bool m_bConflict; + bool m_bTiebreakNeeded; + MDNSHostProbeFn m_fnHostProbeResultCallback; + MDNSServiceProbeFn m_fnServiceProbeResultCallback; + + stcProbeInformation(void); + + bool clear(bool p_bClearUserdata = false); + }; + + /** + stcMDNSService + */ + struct stcMDNSService { + stcMDNSService* m_pNext; + char* m_pcName; + bool m_bAutoName; // Name was set automatically to hostname (if no name was supplied) + char* m_pcService; + char* m_pcProtocol; + uint16_t m_u16Port; + uint8_t m_u8ReplyMask; + stcMDNSServiceTxts m_Txts; + MDNSDynamicServiceTxtCallbackFunc m_fnTxtCallback; + stcProbeInformation m_ProbeInformation; + + stcMDNSService(const char* p_pcName = 0, const char* p_pcService = 0, + const char* p_pcProtocol = 0); + ~stcMDNSService(void); + + bool setName(const char* p_pcName); + bool releaseName(void); + + bool setService(const char* p_pcService); + bool releaseService(void); + + bool setProtocol(const char* p_pcProtocol); + bool releaseProtocol(void); + }; + + /** + stcMDNSServiceQuery + */ + struct stcMDNSServiceQuery { + /** + stcAnswer + */ + struct stcAnswer { + /** + stcTTL + */ + struct stcTTL { + /** + timeoutLevel_t + */ + typedef uint8_t timeoutLevel_t; + /** + TIMEOUTLEVELs + */ + const timeoutLevel_t TIMEOUTLEVEL_UNSET = 0; + const timeoutLevel_t TIMEOUTLEVEL_BASE = 80; + const timeoutLevel_t TIMEOUTLEVEL_INTERVAL = 5; + const timeoutLevel_t TIMEOUTLEVEL_FINAL = 100; + + uint32_t m_u32TTL; + esp8266::polledTimeout::oneShotMs m_TTLTimeout; + timeoutLevel_t m_timeoutLevel; + + using timeoutBase = decltype(m_TTLTimeout); + + stcTTL(void); + bool set(uint32_t p_u32TTL); + + bool flagged(void); + bool restart(void); + + bool prepareDeletion(void); + bool finalTimeoutLevel(void) const; + + timeoutBase::timeType timeout(void) const; + }; +#ifdef MDNS_IP4_SUPPORT + /** + stcIP4Address + */ + struct stcIP4Address { + stcIP4Address* m_pNext; + IPAddress m_IPAddress; + stcTTL m_TTL; + + stcIP4Address(IPAddress p_IPAddress, uint32_t p_u32TTL = 0); + }; +#endif +#ifdef MDNS_IP6_SUPPORT + /** + stcIP6Address + */ + struct stcIP6Address { + stcIP6Address* m_pNext; + IP6Address m_IPAddress; + stcTTL m_TTL; + + stcIP6Address(IPAddress p_IPAddress, uint32_t p_u32TTL = 0); + }; +#endif + + stcAnswer* m_pNext; + // The service domain is the first 'answer' (from PTR answer, using service and + // protocol) to be set Defines the key for additional answer, like host domain, etc. + stcMDNS_RRDomain + m_ServiceDomain; // 1. level answer (PTR), eg. MyESP._http._tcp.local + char* m_pcServiceDomain; + stcTTL m_TTLServiceDomain; + stcMDNS_RRDomain + m_HostDomain; // 2. level answer (SRV, using service domain), eg. esp8266.local + char* m_pcHostDomain; + uint16_t m_u16Port; // 2. level answer (SRV, using service domain), eg. 5000 + stcTTL m_TTLHostDomainAndPort; + stcMDNSServiceTxts m_Txts; // 2. level answer (TXT, using service domain), eg. c#=1 + char* m_pcTxts; + stcTTL m_TTLTxts; +#ifdef MDNS_IP4_SUPPORT + stcIP4Address* + m_pIP4Addresses; // 3. level answer (A, using host domain), eg. 123.456.789.012 +#endif +#ifdef MDNS_IP6_SUPPORT + stcIP6Address* + m_pIP6Addresses; // 3. level answer (AAAA, using host domain), eg. 1234::09 +#endif + uint32_t m_u32ContentFlags; + + stcAnswer(void); + ~stcAnswer(void); + + bool clear(void); + + char* allocServiceDomain(size_t p_stLength); + bool releaseServiceDomain(void); + + char* allocHostDomain(size_t p_stLength); + bool releaseHostDomain(void); + + char* allocTxts(size_t p_stLength); + bool releaseTxts(void); + +#ifdef MDNS_IP4_SUPPORT + bool releaseIP4Addresses(void); + bool addIP4Address(stcIP4Address* p_pIP4Address); + bool removeIP4Address(stcIP4Address* p_pIP4Address); + const stcIP4Address* findIP4Address(const IPAddress& p_IPAddress) const; + stcIP4Address* findIP4Address(const IPAddress& p_IPAddress); + uint32_t IP4AddressCount(void) const; + const stcIP4Address* IP4AddressAtIndex(uint32_t p_u32Index) const; + stcIP4Address* IP4AddressAtIndex(uint32_t p_u32Index); +#endif +#ifdef MDNS_IP6_SUPPORT + bool releaseIP6Addresses(void); + bool addIP6Address(stcIP6Address* p_pIP6Address); + bool removeIP6Address(stcIP6Address* p_pIP6Address); + const stcIP6Address* findIP6Address(const IPAddress& p_IPAddress) const; + stcIP6Address* findIP6Address(const IPAddress& p_IPAddress); + uint32_t IP6AddressCount(void) const; + const stcIP6Address* IP6AddressAtIndex(uint32_t p_u32Index) const; + stcIP6Address* IP6AddressAtIndex(uint32_t p_u32Index); +#endif + }; + + stcMDNSServiceQuery* m_pNext; + stcMDNS_RRDomain m_ServiceTypeDomain; // eg. _http._tcp.local + MDNSServiceQueryCallbackFunc m_fnCallback; + bool m_bLegacyQuery; + uint8_t m_u8SentCount; + esp8266::polledTimeout::oneShotMs m_ResendTimeout; + bool m_bAwaitingAnswers; + stcAnswer* m_pAnswers; + + stcMDNSServiceQuery(void); + ~stcMDNSServiceQuery(void); + + bool clear(void); + + uint32_t answerCount(void) const; + const stcAnswer* answerAtIndex(uint32_t p_u32Index) const; + stcAnswer* answerAtIndex(uint32_t p_u32Index); + uint32_t indexOfAnswer(const stcAnswer* p_pAnswer) const; + + bool addAnswer(stcAnswer* p_pAnswer); + bool removeAnswer(stcAnswer* p_pAnswer); + + stcAnswer* findAnswerForServiceDomain(const stcMDNS_RRDomain& p_ServiceDomain); + stcAnswer* findAnswerForHostDomain(const stcMDNS_RRDomain& p_HostDomain); + }; + + /** + stcMDNSSendParameter + */ + struct stcMDNSSendParameter { + protected: + /** + stcDomainCacheItem + */ + struct stcDomainCacheItem { + stcDomainCacheItem* m_pNext; + const void* m_pHostnameOrService; // Opaque id for host or service domain (pointer) + bool m_bAdditionalData; // Opaque flag for special info (service domain included) + uint16_t m_u16Offset; // Offset in UDP output buffer + + stcDomainCacheItem(const void* p_pHostnameOrService, bool p_bAdditionalData, + uint32_t p_u16Offset); + }; + + public: + uint16_t m_u16ID; // Query ID (used only in lagacy queries) + stcMDNS_RRQuestion* m_pQuestions; // A list of queries + uint8_t m_u8HostReplyMask; // Flags for reply components/answers + bool m_bLegacyQuery; // Flag: Legacy query + bool m_bResponse; // Flag: Response to a query + bool m_bAuthorative; // Flag: Authoritative (owner) response + bool m_bCacheFlush; // Flag: Clients should flush their caches + bool m_bUnicast; // Flag: Unicast response + bool m_bUnannounce; // Flag: Unannounce service + uint16_t m_u16Offset; // Current offset in UDP write buffer (mainly for domain cache) + stcDomainCacheItem* m_pDomainCacheItems; // Cached host and service domains + + stcMDNSSendParameter(void); + ~stcMDNSSendParameter(void); + + bool clear(void); + bool clearCachedNames(void); + + bool shiftOffset(uint16_t p_u16Shift); + + bool addDomainCacheItem(const void* p_pHostnameOrService, bool p_bAdditionalData, + uint16_t p_u16Offset); + uint16_t findCachedDomainOffset(const void* p_pHostnameOrService, + bool p_bAdditionalData) const; + }; + + // Instance variables + stcMDNSService* m_pServices; + UdpContext* m_pUDPContext; + char* m_pcHostname; + stcMDNSServiceQuery* m_pServiceQueries; + MDNSDynamicServiceTxtCallbackFunc m_fnServiceTxtCallback; + stcProbeInformation m_HostProbeInformation; + + /** CONTROL **/ + /* MAINTENANCE */ + bool _process(bool p_bUserContext); + bool _restart(void); + + /* RECEIVING */ + bool _parseMessage(void); + bool _parseQuery(const stcMDNS_MsgHeader& p_Header); + + bool _parseResponse(const stcMDNS_MsgHeader& p_Header); + bool _processAnswers(const stcMDNS_RRAnswer* p_pPTRAnswers); + bool _processPTRAnswer(const stcMDNS_RRAnswerPTR* p_pPTRAnswer, + bool& p_rbFoundNewKeyAnswer); + bool _processSRVAnswer(const stcMDNS_RRAnswerSRV* p_pSRVAnswer, + bool& p_rbFoundNewKeyAnswer); + bool _processTXTAnswer(const stcMDNS_RRAnswerTXT* p_pTXTAnswer); +#ifdef MDNS_IP4_SUPPORT + bool _processAAnswer(const stcMDNS_RRAnswerA* p_pAAnswer); +#endif +#ifdef MDNS_IP6_SUPPORT + bool _processAAAAAnswer(const stcMDNS_RRAnswerAAAA* p_pAAAAAnswer); +#endif + + /* PROBING */ + bool _updateProbeStatus(void); + bool _resetProbeStatus(bool p_bRestart = true); + bool _hasProbesWaitingForAnswers(void) const; + bool _sendHostProbe(void); + bool _sendServiceProbe(stcMDNSService& p_rService); + bool _cancelProbingForHost(void); + bool _cancelProbingForService(stcMDNSService& p_rService); + + /* ANNOUNCE */ + bool _announce(bool p_bAnnounce, bool p_bIncludeServices); + bool _announceService(stcMDNSService& p_rService, bool p_bAnnounce = true); + + /* SERVICE QUERY CACHE */ + bool _hasServiceQueriesWaitingForAnswers(void) const; + bool _checkServiceQueryCache(void); + + /** TRANSFER **/ + /* SENDING */ + bool _sendMDNSMessage(stcMDNSSendParameter& p_SendParameter); + bool _sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter); + bool _prepareMDNSMessage(stcMDNSSendParameter& p_SendParameter, IPAddress p_IPAddress); + bool _sendMDNSServiceQuery(const stcMDNSServiceQuery& p_ServiceQuery); + bool _sendMDNSQuery(const stcMDNS_RRDomain& p_QueryDomain, uint16_t p_u16QueryType, + stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers = 0); + + uint8_t _replyMaskForHost(const stcMDNS_RRHeader& p_RRHeader, + bool* p_pbFullNameMatch = 0) const; + uint8_t _replyMaskForService(const stcMDNS_RRHeader& p_RRHeader, + const stcMDNSService& p_Service, + bool* p_pbFullNameMatch = 0) const; + + /* RESOURCE RECORD */ + bool _readRRQuestion(stcMDNS_RRQuestion& p_rQuestion); + bool _readRRAnswer(stcMDNS_RRAnswer*& p_rpAnswer); +#ifdef MDNS_IP4_SUPPORT + bool _readRRAnswerA(stcMDNS_RRAnswerA& p_rRRAnswerA, uint16_t p_u16RDLength); +#endif + bool _readRRAnswerPTR(stcMDNS_RRAnswerPTR& p_rRRAnswerPTR, uint16_t p_u16RDLength); + bool _readRRAnswerTXT(stcMDNS_RRAnswerTXT& p_rRRAnswerTXT, uint16_t p_u16RDLength); +#ifdef MDNS_IP6_SUPPORT + bool _readRRAnswerAAAA(stcMDNS_RRAnswerAAAA& p_rRRAnswerAAAA, uint16_t p_u16RDLength); +#endif + bool _readRRAnswerSRV(stcMDNS_RRAnswerSRV& p_rRRAnswerSRV, uint16_t p_u16RDLength); + bool _readRRAnswerGeneric(stcMDNS_RRAnswerGeneric& p_rRRAnswerGeneric, + uint16_t p_u16RDLength); + + bool _readRRHeader(stcMDNS_RRHeader& p_rHeader); + bool _readRRDomain(stcMDNS_RRDomain& p_rRRDomain); + bool _readRRDomain_Loop(stcMDNS_RRDomain& p_rRRDomain, uint8_t p_u8Depth); + bool _readRRAttributes(stcMDNS_RRAttributes& p_rAttributes); + + /* DOMAIN NAMES */ + bool _buildDomainForHost(const char* p_pcHostname, stcMDNS_RRDomain& p_rHostDomain) const; + bool _buildDomainForDNSSD(stcMDNS_RRDomain& p_rDNSSDDomain) const; + bool _buildDomainForService(const stcMDNSService& p_Service, bool p_bIncludeName, + stcMDNS_RRDomain& p_rServiceDomain) const; + bool _buildDomainForService(const char* p_pcService, const char* p_pcProtocol, + stcMDNS_RRDomain& p_rServiceDomain) const; +#ifdef MDNS_IP4_SUPPORT + bool _buildDomainForReverseIP4(IPAddress p_IP4Address, + stcMDNS_RRDomain& p_rReverseIP4Domain) const; +#endif +#ifdef MDNS_IP6_SUPPORT + bool _buildDomainForReverseIP6(IPAddress p_IP4Address, + stcMDNS_RRDomain& p_rReverseIP6Domain) const; +#endif + + /* UDP */ + bool _udpReadBuffer(unsigned char* p_pBuffer, size_t p_stLength); + bool _udpRead8(uint8_t& p_ru8Value); + bool _udpRead16(uint16_t& p_ru16Value); + bool _udpRead32(uint32_t& p_ru32Value); + + bool _udpAppendBuffer(const unsigned char* p_pcBuffer, size_t p_stLength); + bool _udpAppend8(uint8_t p_u8Value); + bool _udpAppend16(uint16_t p_u16Value); + bool _udpAppend32(uint32_t p_u32Value); + +#if not defined ESP_8266_MDNS_INCLUDE || defined DEBUG_ESP_MDNS_RESPONDER + bool _udpDump(bool p_bMovePointer = false); + bool _udpDump(unsigned p_uOffset, unsigned p_uLength); +#endif + + /* READ/WRITE MDNS STRUCTS */ + bool _readMDNSMsgHeader(stcMDNS_MsgHeader& p_rMsgHeader); + + bool _write8(uint8_t p_u8Value, stcMDNSSendParameter& p_rSendParameter); + bool _write16(uint16_t p_u16Value, stcMDNSSendParameter& p_rSendParameter); + bool _write32(uint32_t p_u32Value, stcMDNSSendParameter& p_rSendParameter); + + bool _writeMDNSMsgHeader(const stcMDNS_MsgHeader& p_MsgHeader, + stcMDNSSendParameter& p_rSendParameter); + bool _writeMDNSRRAttributes(const stcMDNS_RRAttributes& p_Attributes, + stcMDNSSendParameter& p_rSendParameter); + bool _writeMDNSRRDomain(const stcMDNS_RRDomain& p_Domain, + stcMDNSSendParameter& p_rSendParameter); + bool _writeMDNSHostDomain(const char* m_pcHostname, bool p_bPrependRDLength, + stcMDNSSendParameter& p_rSendParameter); + bool _writeMDNSServiceDomain(const stcMDNSService& p_Service, bool p_bIncludeName, + bool p_bPrependRDLength, + stcMDNSSendParameter& p_rSendParameter); + + bool _writeMDNSQuestion(stcMDNS_RRQuestion& p_Question, + stcMDNSSendParameter& p_rSendParameter); + +#ifdef MDNS_IP4_SUPPORT + bool _writeMDNSAnswer_A(IPAddress p_IPAddress, stcMDNSSendParameter& p_rSendParameter); + bool _writeMDNSAnswer_PTR_IP4(IPAddress p_IPAddress, + stcMDNSSendParameter& p_rSendParameter); +#endif + bool _writeMDNSAnswer_PTR_TYPE(stcMDNSService& p_rService, + stcMDNSSendParameter& p_rSendParameter); + bool _writeMDNSAnswer_PTR_NAME(stcMDNSService& p_rService, + stcMDNSSendParameter& p_rSendParameter); + bool _writeMDNSAnswer_TXT(stcMDNSService& p_rService, + stcMDNSSendParameter& p_rSendParameter); +#ifdef MDNS_IP6_SUPPORT + bool _writeMDNSAnswer_AAAA(IPAddress p_IPAddress, stcMDNSSendParameter& p_rSendParameter); + bool _writeMDNSAnswer_PTR_IP6(IPAddress p_IPAddress, + stcMDNSSendParameter& p_rSendParameter); +#endif + bool _writeMDNSAnswer_SRV(stcMDNSService& p_rService, + stcMDNSSendParameter& p_rSendParameter); + + /** HELPERS **/ + /* UDP CONTEXT */ + bool _callProcess(void); + bool _allocUDPContext(void); + bool _releaseUDPContext(void); + + /* SERVICE QUERY */ + stcMDNSServiceQuery* _allocServiceQuery(void); + bool _removeServiceQuery(stcMDNSServiceQuery* p_pServiceQuery); + bool _removeLegacyServiceQuery(void); + stcMDNSServiceQuery* _findServiceQuery(hMDNSServiceQuery p_hServiceQuery); + stcMDNSServiceQuery* _findLegacyServiceQuery(void); + bool _releaseServiceQueries(void); + stcMDNSServiceQuery* + _findNextServiceQueryByServiceType(const stcMDNS_RRDomain& p_ServiceDomain, + const stcMDNSServiceQuery* p_pPrevServiceQuery); + + /* HOSTNAME */ + bool _setHostname(const char* p_pcHostname); + bool _releaseHostname(void); + + /* SERVICE */ + stcMDNSService* _allocService(const char* p_pcName, const char* p_pcService, + const char* p_pcProtocol, uint16_t p_u16Port); + bool _releaseService(stcMDNSService* p_pService); + bool _releaseServices(void); + + stcMDNSService* _findService(const char* p_pcName, const char* p_pcService, + const char* p_pcProtocol); + stcMDNSService* _findService(const hMDNSService p_hService); + + size_t _countServices(void) const; + + /* SERVICE TXT */ + stcMDNSServiceTxt* _allocServiceTxt(stcMDNSService* p_pService, const char* p_pcKey, + const char* p_pcValue, bool p_bTemp); + bool _releaseServiceTxt(stcMDNSService* p_pService, stcMDNSServiceTxt* p_pTxt); + stcMDNSServiceTxt* _updateServiceTxt(stcMDNSService* p_pService, stcMDNSServiceTxt* p_pTxt, + const char* p_pcValue, bool p_bTemp); + + stcMDNSServiceTxt* _findServiceTxt(stcMDNSService* p_pService, const char* p_pcKey); + stcMDNSServiceTxt* _findServiceTxt(stcMDNSService* p_pService, const hMDNSTxt p_hTxt); + + stcMDNSServiceTxt* _addServiceTxt(stcMDNSService* p_pService, const char* p_pcKey, + const char* p_pcValue, bool p_bTemp); + + stcMDNSServiceTxt* _answerKeyValue(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex); + + bool _collectServiceTxts(stcMDNSService& p_rService); + bool _releaseTempServiceTxts(stcMDNSService& p_rService); + const stcMDNSServiceTxt* _serviceTxts(const char* p_pcName, const char* p_pcService, + const char* p_pcProtocol); + + /* MISC */ +#if not defined ESP_8266_MDNS_INCLUDE || defined DEBUG_ESP_MDNS_RESPONDER + bool _printRRDomain(const stcMDNS_RRDomain& p_rRRDomain) const; + bool _printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const; +#endif +}; + +} // namespace MDNSImplementation + +} // namespace esp8266 + +#include diff --git a/libraries/LEAmDNS/src/LEAmDNS_Control.cpp b/libraries/LEAmDNS/src/LEAmDNS_Control.cpp new file mode 100644 index 00000000..72dc69e3 --- /dev/null +++ b/libraries/LEAmDNS/src/LEAmDNS_Control.cpp @@ -0,0 +1,2089 @@ +/* + LEAmDNS_Control.cpp + + License (MIT license): + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#include +#include +#include +#include +#include +#include + +/* + ESP8266mDNS Control.cpp +*/ + +extern "C" +{ + //#include "user_interface.h" +} + +#include "ESP8266mDNS.h" +#include "LEAmDNS_lwIPdefs.h" +#include "LEAmDNS_Priv.h" + +namespace esp8266 { +/* + LEAmDNS +*/ +namespace MDNSImplementation { + +/** + CONTROL +*/ + +/** + MAINTENANCE +*/ + +/* + MDNSResponder::_process + + Run the MDNS process. + Is called, every time the UDPContext receives data AND + should be called in every 'loop' by calling 'MDNS::update()'. + +*/ +bool MDNSResponder::_process(bool p_bUserContext) { + bool bResult = true; + + if (!p_bUserContext) { + if ((m_pUDPContext) && // UDPContext available AND + (m_pUDPContext->next())) { // has content + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _update: Calling + // _parseMessage\n"));); + bResult = _parseMessage(); + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parsePacket %s\n"), + // (bResult ? "succeeded" : "FAILED"));); + } + } else { + bResult = _updateProbeStatus() && // Probing + _checkServiceQueryCache(); // Service query cache check + } + return bResult; +} + +/* + MDNSResponder::_restart +*/ +bool MDNSResponder::_restart(void) { + return ((_resetProbeStatus(true /*restart*/)) && // Stop and restart probing + (_allocUDPContext())); // Restart UDP +} + +/** + RECEIVING +*/ + +/* + MDNSResponder::_parseMessage +*/ +bool MDNSResponder::_parseMessage(void) { + DEBUG_EX_INFO( + unsigned long ulStartTime = millis(); unsigned uStartMemory = ESP.getFreeHeap(); + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseMessage (Time: %lu ms, heap: %u " + "bytes, from %s(%u), to %s(%u))\n"), + ulStartTime, uStartMemory, + IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str(), + m_pUDPContext->getRemotePort(), + IPAddress(m_pUDPContext->getDestAddress()).toString().c_str(), + m_pUDPContext->getLocalPort());); + // DEBUG_EX_INFO(_udpDump();); + + bool bResult = false; + + stcMDNS_MsgHeader header; + if (_readMDNSMsgHeader(header)) { + if (0 == header.m_4bOpcode) { // A standard query + if (header.m_1bQR) { // Received a response -> answers to a query + // DEBUG_EX_RX(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseMessage: + // Reading answers: ID:%u, Q:%u, A:%u, NS:%u, AR:%u\n"), header.m_u16ID, + // header.m_u16QDCount, header.m_u16ANCount, header.m_u16NSCount, + // header.m_u16ARCount);); + bResult = _parseResponse(header); + } else { // Received a query (Questions) + // DEBUG_EX_RX(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseMessage: + // Reading query: ID:%u, Q:%u, A:%u, NS:%u, AR:%u\n"), header.m_u16ID, + // header.m_u16QDCount, header.m_u16ANCount, header.m_u16NSCount, + // header.m_u16ARCount);); + bResult = _parseQuery(header); + } + } else { + DEBUG_EX_ERR( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseMessage: Received UNEXPECTED " + "opcode:%u. Ignoring message!\n"), + header.m_4bOpcode);); + m_pUDPContext->flush(); + } + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseMessage: FAILED to read header\n"));); + m_pUDPContext->flush(); + } + DEBUG_EX_INFO(unsigned uFreeHeap = ESP.getFreeHeap(); DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseMessage: Done (%s after %lu ms, ate %i bytes, remaining " + "%u)\n\n"), + (bResult ? "Succeeded" : "FAILED"), (millis() - ulStartTime), + (uStartMemory - uFreeHeap), uFreeHeap);); + return bResult; +} + +/* + MDNSResponder::_parseQuery + + Queries are of interest in two cases: + 1. allow for tiebreaking while probing in the case of a race condition between two instances + probing for the same name at the same time + 2. provide answers to questions for our host domain or any presented service + + When reading the questions, a set of (planned) responses is created, eg. a reverse PTR + question for the host domain gets an A (IP address) response, a PTR question for the + _services._dns-sd domain gets a PTR (type) response for any registered service, ... + + As any mDNS responder should be able to handle 'legacy' queries (from DNS clients), this + case is handled here also. Legacy queries have got only one (unicast) question and are + directed to the local DNS port (not the multicast port). + + 1. +*/ +bool MDNSResponder::_parseQuery(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHeader) { + bool bResult = true; + + stcMDNSSendParameter sendParameter; + uint8_t u8HostOrServiceReplies = 0; + for (uint16_t qd = 0; ((bResult) && (qd < p_MsgHeader.m_u16QDCount)); ++qd) { + stcMDNS_RRQuestion questionRR; + if ((bResult = _readRRQuestion(questionRR))) { + // Define host replies, BUT only answer queries after probing is done + u8HostOrServiceReplies = sendParameter.m_u8HostReplyMask + |= (((ProbingStatus_Done == m_HostProbeInformation.m_ProbingStatus)) + ? _replyMaskForHost(questionRR.m_Header, 0) + : 0); + DEBUG_EX_INFO(if (u8HostOrServiceReplies) { + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Host reply needed 0x%X\n"), + u8HostOrServiceReplies); + }); + + // Check tiebreak need for host domain + if (ProbingStatus_InProgress == m_HostProbeInformation.m_ProbingStatus) { + bool bFullNameMatch = false; + if ((_replyMaskForHost(questionRR.m_Header, &bFullNameMatch)) + && (bFullNameMatch)) { + // We're in 'probing' state and someone is asking for our host domain: this + // might be a race-condition: Two host with the same domain names try + // simutanously to probe their domains See: RFC 6762, 8.2 (Tiebraking) + // However, we're using a max. reduced approach for tiebreaking here: The + // higher IP-address wins! + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Possible race-condition for host " + "domain detected while probing.\n"));); + + m_HostProbeInformation.m_bTiebreakNeeded = true; + } + } + + // Define service replies + for (stcMDNSService* pService = m_pServices; pService; pService = pService->m_pNext) { + // Define service replies, BUT only answer queries after probing is done + uint8_t u8ReplyMaskForQuestion + = (((ProbingStatus_Done == pService->m_ProbeInformation.m_ProbingStatus)) + ? _replyMaskForService(questionRR.m_Header, *pService, 0) + : 0); + u8HostOrServiceReplies |= (pService->m_u8ReplyMask |= u8ReplyMaskForQuestion); + DEBUG_EX_INFO(if (u8ReplyMaskForQuestion) { + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Service reply needed for " + "(%s.%s.%s): 0x%X (%s)\n"), + (pService->m_pcName ? : m_pcHostname), pService->m_pcService, + pService->m_pcProtocol, u8ReplyMaskForQuestion, + IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str()); + }); + + // Check tiebreak need for service domain + if (ProbingStatus_InProgress == pService->m_ProbeInformation.m_ProbingStatus) { + bool bFullNameMatch = false; + if ((_replyMaskForService(questionRR.m_Header, *pService, &bFullNameMatch)) + && (bFullNameMatch)) { + // We're in 'probing' state and someone is asking for this service + // domain: this might be a race-condition: Two services with the same + // domain names try simutanously to probe their domains See: RFC + // 6762, 8.2 (Tiebraking) However, we're using a max. reduced approach + // for tiebreaking here: The 'higher' SRV host wins! + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Possible race-condition for " + "service domain %s.%s.%s detected while probing.\n"), + (pService->m_pcName ? : m_pcHostname), pService->m_pcService, + pService->m_pcProtocol);); + + pService->m_ProbeInformation.m_bTiebreakNeeded = true; + } + } + } + + // Handle unicast and legacy specialities + // If only one question asks for unicast reply, the whole reply packet is send + // unicast + if (((DNS_MQUERY_PORT != m_pUDPContext->getRemotePort()) + || // Unicast (maybe legacy) query OR + (questionRR.m_bUnicast)) + && // Expressivly unicast query + (!sendParameter.m_bUnicast)) { + sendParameter.m_bUnicast = true; + sendParameter.m_bCacheFlush = false; + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Unicast response for %s!\n"), + IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str());); + + if ((DNS_MQUERY_PORT != m_pUDPContext->getRemotePort()) + && // Unicast (maybe legacy) query AND + (1 == p_MsgHeader.m_u16QDCount) && // Only one question AND + ((sendParameter.m_u8HostReplyMask) || // Host replies OR + (u8HostOrServiceReplies))) { // Host or service replies available + // We're a match for this legacy query, BUT + // make sure, that the query comes from a local host + ip_addr_t local; + ip_addr_t netmask; + ip_addr_t remote; + remote = m_pUDPContext->getRemoteAddress(); + local = WiFi.localIP(); + netmask = WiFi.subnetMask(); + if (ip4_addr_netcmp(&remote, &local, &netmask)) + // ip_info IPInfo_Local; + // ip_info IPInfo_Remote; + // if (((IPInfo_Remote.ip.addr = m_pUDPContext->getRemoteAddress())) + // && (((wifi_get_ip_info(SOFTAP_IF, &IPInfo_Local)) + // && (ip4_addr_netcmp(&IPInfo_Remote.ip, &IPInfo_Local.ip, + // &IPInfo_Local.netmask))) + // || // Remote IP in SOFTAP's subnet OR + // ((wifi_get_ip_info(STATION_IF, &IPInfo_Local)) + // && (ip4_addr_netcmp( + // &IPInfo_Remote.ip, &IPInfo_Local.ip, + // &IPInfo_Local.netmask))))) // Remote IP in STATION's subnet + { + DEBUG_EX_RX(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Legacy query from local host " + "%s, id %u!\n"), + IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str(), + p_MsgHeader.m_u16ID);); + + sendParameter.m_u16ID = p_MsgHeader.m_u16ID; + sendParameter.m_bLegacyQuery = true; + sendParameter.m_pQuestions = new stcMDNS_RRQuestion; + if ((bResult = (0 != sendParameter.m_pQuestions))) { + sendParameter.m_pQuestions->m_Header.m_Domain + = questionRR.m_Header.m_Domain; + sendParameter.m_pQuestions->m_Header.m_Attributes.m_u16Type + = questionRR.m_Header.m_Attributes.m_u16Type; + sendParameter.m_pQuestions->m_Header.m_Attributes.m_u16Class + = questionRR.m_Header.m_Attributes.m_u16Class; + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: FAILED to add legacy " + "question!\n"));); + } + } else { + DEBUG_EX_RX( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: Legacy " + "query from NON-LOCAL host!\n"));); + bResult = false; + } + } + } + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: FAILED to read question!\n"));); + } + } // for questions + + // DEBUG_EX_INFO(if (u8HostOrServiceReplies) { DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] + // _parseQuery: Reply needed: %u (%s: %s->%s)\n"), u8HostOrServiceReplies, + // clsTimeSyncer::timestr(), + // IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str(), + // IPAddress(m_pUDPContext->getDestAddress()).toString().c_str()); } ); + + // Handle known answers + uint32_t u32Answers + = (p_MsgHeader.m_u16ANCount + p_MsgHeader.m_u16NSCount + p_MsgHeader.m_u16ARCount); + DEBUG_EX_INFO(if ((u8HostOrServiceReplies) && (u32Answers)) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: Known answers(%u):\n"), + u32Answers); + }); + + for (uint32_t an = 0; ((bResult) && (an < u32Answers)); ++an) { + stcMDNS_RRAnswer* pKnownRRAnswer = 0; + if (((bResult = _readRRAnswer(pKnownRRAnswer))) && (pKnownRRAnswer)) { + if ((DNS_RRTYPE_ANY != pKnownRRAnswer->m_Header.m_Attributes.m_u16Type) + && // No ANY type answer + (DNS_RRCLASS_ANY + != pKnownRRAnswer->m_Header.m_Attributes.m_u16Class)) { // No ANY class answer + // Find match between planned answer (sendParameter.m_u8HostReplyMask) and this + // 'known answer' + uint8_t u8HostMatchMask = (sendParameter.m_u8HostReplyMask + & _replyMaskForHost(pKnownRRAnswer->m_Header)); + if ((u8HostMatchMask) + && // The RR in the known answer matches an RR we are planning to send, AND + ((MDNS_HOST_TTL / 2) + <= pKnownRRAnswer->m_u32TTL)) // The TTL of the known answer is longer + // than half of the new host TTL (120s) + { + // Compare contents + if (AnswerType_PTR == pKnownRRAnswer->answerType()) { + stcMDNS_RRDomain hostDomain; + if ((_buildDomainForHost(m_pcHostname, hostDomain)) + && (((stcMDNS_RRAnswerPTR*)pKnownRRAnswer)->m_PTRDomain + == hostDomain)) { + // Host domain match +#ifdef MDNS_IP4_SUPPORT + if (u8HostMatchMask & ContentFlag_PTR_IP4) { + // IP4 PTR was asked for, but is already known -> skipping + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: IP4 PTR already " + "known... skipping!\n"));); + sendParameter.m_u8HostReplyMask &= ~ContentFlag_PTR_IP4; + } +#endif +#ifdef MDNS_IP6_SUPPORT + if (u8HostMatchMask & ContentFlag_PTR_IP6) { + // IP6 PTR was asked for, but is already known -> skipping + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: IP6 PTR already " + "known... skipping!\n"));); + sendParameter.m_u8HostReplyMask &= ~ContentFlag_PTR_IP6; + } +#endif + } + } else if (u8HostMatchMask & ContentFlag_A) { + // IP4 address was asked for +#ifdef MDNS_IP4_SUPPORT + if ((AnswerType_A == pKnownRRAnswer->answerType()) + && (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress + == m_pUDPContext->getInputNetif()->ip_addr)) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: IP4 address already " + "known... skipping!\n"));); + sendParameter.m_u8HostReplyMask &= ~ContentFlag_A; + } // else: RData NOT IP4 length !! +#endif + } else if (u8HostMatchMask & ContentFlag_AAAA) { + // IP6 address was asked for +#ifdef MDNS_IP6_SUPPORT + if ((AnswerType_AAAA == pAnswerRR->answerType()) + && (((stcMDNS_RRAnswerAAAA*)pAnswerRR)->m_IPAddress + == _getResponseMulticastInterface())) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: IP6 address already " + "known... skipping!\n"));); + sendParameter.m_u8HostReplyMask &= ~ContentFlag_AAAA; + } // else: RData NOT IP6 length !! +#endif + } + } // Host match /*and TTL*/ + + // + // Check host tiebreak possibility + if (m_HostProbeInformation.m_bTiebreakNeeded) { + stcMDNS_RRDomain hostDomain; + if ((_buildDomainForHost(m_pcHostname, hostDomain)) + && (pKnownRRAnswer->m_Header.m_Domain == hostDomain)) { + // Host domain match +#ifdef MDNS_IP4_SUPPORT + if (AnswerType_A == pKnownRRAnswer->answerType()) { + IPAddress localIPAddress(m_pUDPContext->getInputNetif()->ip_addr); + if (((stcMDNS_RRAnswerA*)pKnownRRAnswer)->m_IPAddress + == localIPAddress) { + // SAME IP address -> We've received an old message from + // ourselves (same IP) + DEBUG_EX_RX(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Tiebreak (IP4) WON (was " + "an old message)!\n"));); + m_HostProbeInformation.m_bTiebreakNeeded = false; + } else { + if ((uint32_t)(((stcMDNS_RRAnswerA*)pKnownRRAnswer) + ->m_IPAddress) + > (uint32_t) + localIPAddress) { // The OTHER IP is 'higher' -> LOST + // LOST tiebreak + DEBUG_EX_RX(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Tiebreak (IP4) LOST " + "(lower)!\n"));); + _cancelProbingForHost(); + m_HostProbeInformation.m_bTiebreakNeeded = false; + } else { // WON tiebreak + // TiebreakState = TiebreakState_Won; // We received an + // 'old' message from ourselves -> Just ignore + DEBUG_EX_RX(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Tiebreak (IP4) WON " + "(higher IP)!\n"));); + m_HostProbeInformation.m_bTiebreakNeeded = false; + } + } + } +#endif +#ifdef MDNS_IP6_SUPPORT + if (AnswerType_AAAA == pAnswerRR->answerType()) { + // TODO + } +#endif + } + } // Host tiebreak possibility + + // Check service answers + for (stcMDNSService* pService = m_pServices; pService; + pService = pService->m_pNext) { + uint8_t u8ServiceMatchMask + = (pService->m_u8ReplyMask + & _replyMaskForService(pKnownRRAnswer->m_Header, *pService)); + + if ((u8ServiceMatchMask) && // The RR in the known answer matches an RR we + // are planning to send, AND + ((MDNS_SERVICE_TTL / 2) + <= pKnownRRAnswer + ->m_u32TTL)) // The TTL of the known answer is longer than half + // of the new service TTL (4500s) + { + if (AnswerType_PTR == pKnownRRAnswer->answerType()) { + stcMDNS_RRDomain serviceDomain; + if ((u8ServiceMatchMask & ContentFlag_PTR_TYPE) + && (_buildDomainForService(*pService, false, serviceDomain)) + && (serviceDomain + == ((stcMDNS_RRAnswerPTR*)pKnownRRAnswer)->m_PTRDomain)) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Service type PTR " + "already known... skipping!\n"));); + pService->m_u8ReplyMask &= ~ContentFlag_PTR_TYPE; + } + if ((u8ServiceMatchMask & ContentFlag_PTR_NAME) + && (_buildDomainForService(*pService, true, serviceDomain)) + && (serviceDomain + == ((stcMDNS_RRAnswerPTR*)pKnownRRAnswer)->m_PTRDomain)) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Service name PTR " + "already known... skipping!\n"));); + pService->m_u8ReplyMask &= ~ContentFlag_PTR_NAME; + } + } else if (u8ServiceMatchMask & ContentFlag_SRV) { + DEBUG_EX_ERR(if (AnswerType_SRV != pKnownRRAnswer->answerType()) + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: ERROR! " + "INVALID answer type (SRV)!\n"));); + stcMDNS_RRDomain hostDomain; + if ((_buildDomainForHost(m_pcHostname, hostDomain)) + && (hostDomain + == ((stcMDNS_RRAnswerSRV*)pKnownRRAnswer) + ->m_SRVDomain)) { // Host domain match + if ((MDNS_SRV_PRIORITY + == ((stcMDNS_RRAnswerSRV*)pKnownRRAnswer)->m_u16Priority) + && (MDNS_SRV_WEIGHT + == ((stcMDNS_RRAnswerSRV*)pKnownRRAnswer)->m_u16Weight) + && (pService->m_u16Port + == ((stcMDNS_RRAnswerSRV*)pKnownRRAnswer)->m_u16Port)) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Service SRV answer " + "already known... skipping!\n"));); + pService->m_u8ReplyMask &= ~ContentFlag_SRV; + } // else: Small differences -> send update message + } + } else if (u8ServiceMatchMask & ContentFlag_TXT) { + DEBUG_EX_ERR(if (AnswerType_TXT != pKnownRRAnswer->answerType()) + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: ERROR! " + "INVALID answer type (TXT)!\n"));); + _collectServiceTxts(*pService); + if (pService->m_Txts + == ((stcMDNS_RRAnswerTXT*)pKnownRRAnswer)->m_Txts) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Service TXT answer " + "already known... skipping!\n"));); + pService->m_u8ReplyMask &= ~ContentFlag_TXT; + } + _releaseTempServiceTxts(*pService); + } + } // Service match and enough TTL + + // + // Check service tiebreak possibility + if (pService->m_ProbeInformation.m_bTiebreakNeeded) { + stcMDNS_RRDomain serviceDomain; + if ((_buildDomainForService(*pService, true, serviceDomain)) + && (pKnownRRAnswer->m_Header.m_Domain == serviceDomain)) { + // Service domain match + if (AnswerType_SRV == pKnownRRAnswer->answerType()) { + stcMDNS_RRDomain hostDomain; + if ((_buildDomainForHost(m_pcHostname, hostDomain)) + && (hostDomain + == ((stcMDNS_RRAnswerSRV*)pKnownRRAnswer) + ->m_SRVDomain)) { // Host domain match + // We've received an old message from ourselves (same SRV) + DEBUG_EX_RX(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Tiebreak (SRV) won " + "(was an old message)!\n"));); + pService->m_ProbeInformation.m_bTiebreakNeeded = false; + } else { + if (((stcMDNS_RRAnswerSRV*)pKnownRRAnswer)->m_SRVDomain + > hostDomain) { // The OTHER domain is 'higher' -> LOST + // LOST tiebreak + DEBUG_EX_RX(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Tiebreak (SRV) " + "LOST (lower)!\n"));); + _cancelProbingForService(*pService); + pService->m_ProbeInformation.m_bTiebreakNeeded = false; + } else { // WON tiebreak + // TiebreakState = TiebreakState_Won; // We received + // an 'old' message from ourselves -> Just ignore + DEBUG_EX_RX(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Tiebreak (SRV) " + "won (higher)!\n"));); + pService->m_ProbeInformation.m_bTiebreakNeeded = false; + } + } + } + } + } // service tiebreak possibility + } // for services + } // ANY answers + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: FAILED to read known answer!\n"));); + } + + if (pKnownRRAnswer) { + delete pKnownRRAnswer; + pKnownRRAnswer = 0; + } + } // for answers + + if (bResult) { + // Check, if a reply is needed + uint8_t u8ReplyNeeded = sendParameter.m_u8HostReplyMask; + for (stcMDNSService* pService = m_pServices; pService; pService = pService->m_pNext) { + u8ReplyNeeded |= pService->m_u8ReplyMask; + } + + if (u8ReplyNeeded) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: Sending answer(0x%X)...\n"), + u8ReplyNeeded);); + + sendParameter.m_bResponse = true; + sendParameter.m_bAuthorative = true; + + bResult = _sendMDNSMessage(sendParameter); + } + DEBUG_EX_INFO(else { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: No reply needed\n")); + }); + } else { + DEBUG_EX_ERR( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: Something FAILED!\n"));); + m_pUDPContext->flush(); + } + + // + // Check and reset tiebreak-states + if (m_HostProbeInformation.m_bTiebreakNeeded) { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseQuery: UNSOLVED tiebreak-need for host domain!\n"));); + m_HostProbeInformation.m_bTiebreakNeeded = false; + } + for (stcMDNSService* pService = m_pServices; pService; pService = pService->m_pNext) { + if (pService->m_ProbeInformation.m_bTiebreakNeeded) { + DEBUG_EX_ERR( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: UNSOLVED " + "tiebreak-need for service domain (%s.%s.%s)\n"), + (pService->m_pcName ? : m_pcHostname), + pService->m_pcService, pService->m_pcProtocol);); + pService->m_ProbeInformation.m_bTiebreakNeeded = false; + } + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseQuery: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_parseResponse + + Responses are of interest in two cases: + 1. find domain name conflicts while probing + 2. get answers to service queries + + In both cases any included questions are ignored + + 1. If any answer has a domain name similar to one of the domain names we're planning to use + (and are probing for), then we've got a 'probing conflict'. The conflict has to be solved on + our side of the conflict (eg. by setting a new hostname and restart probing). The callback + 'm_fnProbeResultCallback' is called with 'p_bProbeResult=false' in this case. + + 2. Service queries like '_http._tcp.local' will (if available) produce PTR, SRV, TXT and + A/AAAA answers. All stored answers are pivoted by the service instance name (from the PTR + record). Other answer parts, like host domain or IP address are than attached to this + element. Any answer part carries a TTL, this is also stored (incl. the reception time); if + the TTL is '0' the answer (part) is withdrawn by the sender and should be removed from any + cache. RFC 6762, 10.1 proposes to set the caches TTL-value to 1 second in such a case and to + delete the item only, if no update has has taken place in this second. Answer parts may + arrive in 'unsorted' order, so they are grouped into three levels: Level 1: PRT - names the + service instance (and is used as pivot), voids all other parts if is withdrawn or outdates + Level 2: SRV - links the instance name to a host domain and port, voids A/AAAA parts if is + withdrawn or outdates TXT - links the instance name to services TXTs Level 3: A/AAAA - links + the host domain to an IP address +*/ +bool MDNSResponder::_parseResponse(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHeader) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseResponse\n"));); + // DEBUG_EX_INFO(_udpDump();); + + bool bResult = false; + + // A response should be the result of a query or a probe + if ((_hasServiceQueriesWaitingForAnswers()) || // Waiting for query answers OR + (_hasProbesWaitingForAnswers())) { // Probe responses + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseResponse: Received a response\n")); + //_udpDump(); + ); + + bResult = true; + // + // Ignore questions here + stcMDNS_RRQuestion dummyRRQ; + for (uint16_t qd = 0; ((bResult) && (qd < p_MsgHeader.m_u16QDCount)); ++qd) { + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseResponse: Received a " + "response containing a question... ignoring!\n"));); + bResult = _readRRQuestion(dummyRRQ); + } // for queries + + // + // Read and collect answers + stcMDNS_RRAnswer* pCollectedRRAnswers = 0; + uint32_t u32NumberOfAnswerRRs + = (p_MsgHeader.m_u16ANCount + p_MsgHeader.m_u16NSCount + p_MsgHeader.m_u16ARCount); + for (uint32_t an = 0; ((bResult) && (an < u32NumberOfAnswerRRs)); ++an) { + stcMDNS_RRAnswer* pRRAnswer = 0; + if (((bResult = _readRRAnswer(pRRAnswer))) && (pRRAnswer)) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseResponse: + // ADDING answer!\n"));); + pRRAnswer->m_pNext = pCollectedRRAnswers; + pCollectedRRAnswers = pRRAnswer; + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseResponse: FAILED to read answer!\n"));); + if (pRRAnswer) { + delete pRRAnswer; + pRRAnswer = 0; + } + bResult = false; + } + } // for answers + + // + // Process answers + if (bResult) { + bResult = ((!pCollectedRRAnswers) || (_processAnswers(pCollectedRRAnswers))); + } else { // Some failure while reading answers + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _parseResponse: FAILED to read answers!\n"));); + m_pUDPContext->flush(); + } + + // Delete collected answers + while (pCollectedRRAnswers) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseResponse: + // DELETING answer!\n"));); + stcMDNS_RRAnswer* pNextAnswer = pCollectedRRAnswers->m_pNext; + delete pCollectedRRAnswers; + pCollectedRRAnswers = pNextAnswer; + } + } else { // Received an unexpected response -> ignore + /* DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseResponse: Received an + unexpected response... ignoring!\nDUMP:\n")); bool bDumpResult = true; for + (uint16_t qd=0; ((bDumpResult) && (qdflush(); + bResult = true; + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _parseResponse: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_processAnswers + Host: + A (0x01): eg. esp8266.local A OP TTL 123.456.789.012 + AAAA (01Cx): eg. esp8266.local AAAA OP TTL 1234:5678::90 + PTR (0x0C, IP4): eg. 012.789.456.123.in-addr.arpa PTR OP TTL esp8266.local + PTR (0x0C, IP6): eg. 90.0.0.0.0.0.0.0.0.0.0.0.78.56.34.12.ip6.arpa PTR OP TTL + esp8266.local Service: PTR (0x0C, srv name): eg. _http._tcp.local PTR OP TTL + MyESP._http._tcp.local PTR (0x0C, srv type): eg. _services._dns-sd._udp.local PTR OP TTL + _http._tcp.local SRV (0x21): eg. MyESP._http._tcp.local SRV OP TTL PRIORITY + WEIGHT PORT esp8266.local TXT (0x10): eg. MyESP._http._tcp.local TXT OP TTL c#=1 + +*/ +bool MDNSResponder::_processAnswers(const MDNSResponder::stcMDNS_RRAnswer* p_pAnswers) { + bool bResult = false; + + if (p_pAnswers) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAnswers: Processing answers...\n"));); + bResult = true; + + // Answers may arrive in an unexpected order. So we loop our answers as long, as we + // can connect new information to service queries + bool bFoundNewKeyAnswer; + do { + bFoundNewKeyAnswer = false; + + const stcMDNS_RRAnswer* pRRAnswer = p_pAnswers; + while ((pRRAnswer) && (bResult)) { + // 1. level answer (PTR) + if (AnswerType_PTR == pRRAnswer->answerType()) { + // eg. _http._tcp.local PTR xxxx xx MyESP._http._tcp.local + bResult = _processPTRAnswer( + (stcMDNS_RRAnswerPTR*)pRRAnswer, + bFoundNewKeyAnswer); // May 'enable' new SRV or TXT answers to be + // linked to queries + } + // 2. level answers + // SRV -> host domain and port + else if (AnswerType_SRV == pRRAnswer->answerType()) { + // eg. MyESP_http._tcp.local SRV xxxx xx yy zz 5000 esp8266.local + bResult = _processSRVAnswer( + (stcMDNS_RRAnswerSRV*)pRRAnswer, + bFoundNewKeyAnswer); // May 'enable' new A/AAAA answers to be linked to + // queries + } + // TXT -> Txts + else if (AnswerType_TXT == pRRAnswer->answerType()) { + // eg. MyESP_http._tcp.local TXT xxxx xx c#=1 + bResult = _processTXTAnswer((stcMDNS_RRAnswerTXT*)pRRAnswer); + } + // 3. level answers +#ifdef MDNS_IP4_SUPPORT + // A -> IP4Address + else if (AnswerType_A == pRRAnswer->answerType()) { + // eg. esp8266.local A xxxx xx 192.168.2.120 + bResult = _processAAnswer((stcMDNS_RRAnswerA*)pRRAnswer); + } +#endif +#ifdef MDNS_IP6_SUPPORT + // AAAA -> IP6Address + else if (AnswerType_AAAA == pRRAnswer->answerType()) { + // eg. esp8266.local AAAA xxxx xx 09cf::0c + bResult = _processAAAAAnswer((stcMDNS_RRAnswerAAAA*)pRRAnswer); + } +#endif + + // Finally check for probing conflicts + // Host domain + if ((ProbingStatus_InProgress == m_HostProbeInformation.m_ProbingStatus) + && ((AnswerType_A == pRRAnswer->answerType()) + || (AnswerType_AAAA == pRRAnswer->answerType()))) { + stcMDNS_RRDomain hostDomain; + if ((_buildDomainForHost(m_pcHostname, hostDomain)) + && (pRRAnswer->m_Header.m_Domain == hostDomain)) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAnswers: Probing CONFLICT found " + "with: %s.local\n"), + m_pcHostname);); + _cancelProbingForHost(); + } + } + // Service domains + for (stcMDNSService* pService = m_pServices; pService; + pService = pService->m_pNext) { + if ((ProbingStatus_InProgress + == pService->m_ProbeInformation.m_ProbingStatus) + && ((AnswerType_TXT == pRRAnswer->answerType()) + || (AnswerType_SRV == pRRAnswer->answerType()))) { + stcMDNS_RRDomain serviceDomain; + if ((_buildDomainForService(*pService, true, serviceDomain)) + && (pRRAnswer->m_Header.m_Domain == serviceDomain)) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAnswers: Probing CONFLICT found " + "with: %s.%s.%s\n"), + (pService->m_pcName ? : m_pcHostname), pService->m_pcService, + pService->m_pcProtocol);); + _cancelProbingForService(*pService); + } + } + } + + pRRAnswer = pRRAnswer->m_pNext; // Next collected answer + } // while (answers) + } while ((bFoundNewKeyAnswer) && (bResult)); + } // else: No answers provided + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processAnswers: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_processPTRAnswer +*/ +bool MDNSResponder::_processPTRAnswer(const MDNSResponder::stcMDNS_RRAnswerPTR* p_pPTRAnswer, + bool& p_rbFoundNewKeyAnswer) { + bool bResult = false; + + if ((bResult = (0 != p_pPTRAnswer))) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processPTRAnswer: Processing PTR answers...\n"));); + // eg. _http._tcp.local PTR xxxx xx MyESP._http._tcp.local + // Check pending service queries for eg. '_http._tcp' + + stcMDNSServiceQuery* pServiceQuery + = _findNextServiceQueryByServiceType(p_pPTRAnswer->m_Header.m_Domain, 0); + while (pServiceQuery) { + if (pServiceQuery->m_bAwaitingAnswers) { + // Find answer for service domain (eg. MyESP._http._tcp.local) + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = pServiceQuery->findAnswerForServiceDomain(p_pPTRAnswer->m_PTRDomain); + if (pSQAnswer) { // existing answer + if (p_pPTRAnswer->m_u32TTL) { // Received update message + pSQAnswer->m_TTLServiceDomain.set( + p_pPTRAnswer->m_u32TTL); // Update TTL tag + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processPTRAnswer: Updated TTL(%d) for "), + (int)p_pPTRAnswer->m_u32TTL); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR("\n"));); + } else { // received goodbye-message + pSQAnswer->m_TTLServiceDomain + .prepareDeletion(); // Prepare answer deletion according to RFC + // 6762, 10.1 + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processPTRAnswer: 'Goodbye' received for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR("\n"));); + } + } else if ((p_pPTRAnswer->m_u32TTL) && // Not just a goodbye-message + ((pSQAnswer + = new stcMDNSServiceQuery::stcAnswer))) // Not yet included -> add + // answer + { + pSQAnswer->m_ServiceDomain = p_pPTRAnswer->m_PTRDomain; + pSQAnswer->m_u32ContentFlags |= ServiceQueryAnswerType_ServiceDomain; + pSQAnswer->m_TTLServiceDomain.set(p_pPTRAnswer->m_u32TTL); + pSQAnswer->releaseServiceDomain(); + + bResult = pServiceQuery->addAnswer(pSQAnswer); + p_rbFoundNewKeyAnswer = true; + if (pServiceQuery->m_fnCallback) { + MDNSServiceInfo serviceInfo(*this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer)); + pServiceQuery->m_fnCallback( + serviceInfo, + static_cast(ServiceQueryAnswerType_ServiceDomain), + true); + } + } + } + pServiceQuery = _findNextServiceQueryByServiceType(p_pPTRAnswer->m_Header.m_Domain, + pServiceQuery); + } + } // else: No p_pPTRAnswer + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processPTRAnswer: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_processSRVAnswer +*/ +bool MDNSResponder::_processSRVAnswer(const MDNSResponder::stcMDNS_RRAnswerSRV* p_pSRVAnswer, + bool& p_rbFoundNewKeyAnswer) { + bool bResult = false; + + if ((bResult = (0 != p_pSRVAnswer))) { + // eg. MyESP._http._tcp.local SRV xxxx xx yy zz 5000 esp8266.local + + stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; + while (pServiceQuery) { + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = pServiceQuery->findAnswerForServiceDomain(p_pSRVAnswer->m_Header.m_Domain); + if (pSQAnswer) // Answer for this service domain (eg. MyESP._http._tcp.local) + // available + { + if (p_pSRVAnswer->m_u32TTL) { // First or update message (TTL != 0) + pSQAnswer->m_TTLHostDomainAndPort.set( + p_pSRVAnswer->m_u32TTL); // Update TTL tag + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processSRVAnswer: Updated TTL(%d) for "), + (int)p_pSRVAnswer->m_u32TTL); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" host domain and port\n"));); + // Host domain & Port + if ((pSQAnswer->m_HostDomain != p_pSRVAnswer->m_SRVDomain) + || (pSQAnswer->m_u16Port != p_pSRVAnswer->m_u16Port)) { + pSQAnswer->m_HostDomain = p_pSRVAnswer->m_SRVDomain; + pSQAnswer->releaseHostDomain(); + pSQAnswer->m_u16Port = p_pSRVAnswer->m_u16Port; + pSQAnswer->m_u32ContentFlags + |= ServiceQueryAnswerType_HostDomainAndPort; + + p_rbFoundNewKeyAnswer = true; + if (pServiceQuery->m_fnCallback) { + MDNSServiceInfo serviceInfo( + *this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer)); + pServiceQuery->m_fnCallback( + serviceInfo, + static_cast( + ServiceQueryAnswerType_HostDomainAndPort), + true); + } + } + } else { // Goodby message + pSQAnswer->m_TTLHostDomainAndPort + .prepareDeletion(); // Prepare answer deletion according to RFC + // 6762, 10.1 + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processSRVAnswer: 'Goodbye' received for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" host domain and port\n"));); + } + } + pServiceQuery = pServiceQuery->m_pNext; + } // while(service query) + } // else: No p_pSRVAnswer + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processSRVAnswer: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_processTXTAnswer +*/ +bool MDNSResponder::_processTXTAnswer(const MDNSResponder::stcMDNS_RRAnswerTXT* p_pTXTAnswer) { + bool bResult = false; + + if ((bResult = (0 != p_pTXTAnswer))) { + // eg. MyESP._http._tcp.local TXT xxxx xx c#=1 + + stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; + while (pServiceQuery) { + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = pServiceQuery->findAnswerForServiceDomain(p_pTXTAnswer->m_Header.m_Domain); + if (pSQAnswer) // Answer for this service domain (eg. MyESP._http._tcp.local) + // available + { + if (p_pTXTAnswer->m_u32TTL) { // First or update message + pSQAnswer->m_TTLTxts.set(p_pTXTAnswer->m_u32TTL); // Update TTL tag + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processTXTAnswer: Updated TTL(%d) for "), + (int)p_pTXTAnswer->m_u32TTL); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" TXTs\n"));); + if (!pSQAnswer->m_Txts.compare(p_pTXTAnswer->m_Txts)) { + pSQAnswer->m_Txts = p_pTXTAnswer->m_Txts; + pSQAnswer->m_u32ContentFlags |= ServiceQueryAnswerType_Txts; + pSQAnswer->releaseTxts(); + + if (pServiceQuery->m_fnCallback) { + MDNSServiceInfo serviceInfo( + *this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer)); + pServiceQuery->m_fnCallback( + serviceInfo, + static_cast(ServiceQueryAnswerType_Txts), true); + } + } + } else { // Goodby message + pSQAnswer->m_TTLTxts.prepareDeletion(); // Prepare answer deletion + // according to RFC 6762, 10.1 + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processTXTAnswer: 'Goodbye' received for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" TXTs\n"));); + } + } + pServiceQuery = pServiceQuery->m_pNext; + } // while(service query) + } // else: No p_pTXTAnswer + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processTXTAnswer: FAILED!\n")); + }); + return bResult; +} + +#ifdef MDNS_IP4_SUPPORT +/* + MDNSResponder::_processAAnswer +*/ +bool MDNSResponder::_processAAnswer(const MDNSResponder::stcMDNS_RRAnswerA* p_pAAnswer) { + bool bResult = false; + + if ((bResult = (0 != p_pAAnswer))) { + // eg. esp8266.local A xxxx xx 192.168.2.120 + + stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; + while (pServiceQuery) { + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = pServiceQuery->findAnswerForHostDomain(p_pAAnswer->m_Header.m_Domain); + if (pSQAnswer) { // Answer for this host domain (eg. esp8266.local) available + stcMDNSServiceQuery::stcAnswer::stcIP4Address* pIP4Address + = pSQAnswer->findIP4Address(p_pAAnswer->m_IPAddress); + if (pIP4Address) { + // Already known IP4 address + if (p_pAAnswer->m_u32TTL) { // Valid TTL -> Update answers TTL + pIP4Address->m_TTL.set(p_pAAnswer->m_u32TTL); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAAnswer: Updated TTL(%d) for "), + (int)p_pAAnswer->m_u32TTL); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P( + PSTR(" IP4Address (%s)\n"), + pIP4Address->m_IPAddress.toString().c_str());); + } else { // 'Goodbye' message for known IP4 address + pIP4Address->m_TTL.prepareDeletion(); // Prepare answer deletion + // according to RFC 6762, 10.1 + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAAnswer: 'Goodbye' received for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P( + PSTR(" IP4 address (%s)\n"), + pIP4Address->m_IPAddress.toString().c_str());); + } + } else { + // Until now unknown IP4 address -> Add (if the message isn't just a + // 'Goodbye' note) + if (p_pAAnswer->m_u32TTL) { // NOT just a 'Goodbye' message + pIP4Address = new stcMDNSServiceQuery::stcAnswer::stcIP4Address( + p_pAAnswer->m_IPAddress, p_pAAnswer->m_u32TTL); + if ((pIP4Address) && (pSQAnswer->addIP4Address(pIP4Address))) { + pSQAnswer->m_u32ContentFlags |= ServiceQueryAnswerType_IP4Address; + if (pServiceQuery->m_fnCallback) { + MDNSServiceInfo serviceInfo( + *this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer)); + pServiceQuery->m_fnCallback( + serviceInfo, + static_cast(ServiceQueryAnswerType_IP4Address), + true); + } + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAAnswer: FAILED to add IP4 " + "address (%s)!\n"), + p_pAAnswer->m_IPAddress.toString().c_str());); + } + } + } + } + pServiceQuery = pServiceQuery->m_pNext; + } // while(service query) + } // else: No p_pAAnswer + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _processAAnswer: FAILED!\n")); + }); + return bResult; +} +#endif + +#ifdef MDNS_IP6_SUPPORT +/* + MDNSResponder::_processAAAAAnswer +*/ +bool MDNSResponder::_processAAAAAnswer(const MDNSResponder::stcMDNS_RRAnswerAAAA* p_pAAAAAnswer) { + bool bResult = false; + + if ((bResult = (0 != p_pAAAAAnswer))) { + // eg. esp8266.local AAAA xxxx xx 0bf3::0c + + stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; + while (pServiceQuery) { + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = pServiceQuery->findAnswerForHostDomain(p_pAAAAAnswer->m_Header.m_Domain); + if (pSQAnswer) { // Answer for this host domain (eg. esp8266.local) available + stcIP6Address* pIP6Address + = pSQAnswer->findIP6Address(p_pAAAAAnswer->m_IPAddress); + if (pIP6Address) { + // Already known IP6 address + if (p_pAAAAAnswer->m_u32TTL) { // Valid TTL -> Update answers TTL + pIP6Address->m_TTL.set(p_pAAAAAnswer->m_u32TTL); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAAnswer: Updated TTL(%lu) for "), + p_pAAAAAnswer->m_u32TTL); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P( + PSTR(" IP6 address (%s)\n"), + pIP6Address->m_IPAddress.toString().c_str());); + } else { // 'Goodbye' message for known IP6 address + pIP6Address->m_TTL.prepareDeletion(); // Prepare answer deletion + // according to RFC 6762, 10.1 + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAAnswer: 'Goodbye' received for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P( + PSTR(" IP6 address (%s)\n"), + pIP6Address->m_IPAddress.toString().c_str());); + } + } else { + // Until now unknown IP6 address -> Add (if the message isn't just a + // 'Goodbye' note) + if (p_pAAAAAnswer->m_u32TTL) { // NOT just a 'Goodbye' message + pIP6Address = new stcIP6Address(p_pAAAAAnswer->m_IPAddress, + p_pAAAAAnswer->m_u32TTL); + if ((pIP6Address) && (pSQAnswer->addIP6Address(pIP6Address))) { + pSQAnswer->m_u32ContentFlags |= ServiceQueryAnswerType_IP6Address; + + if (pServiceQuery->m_fnCallback) { + pServiceQuery->m_fnCallback( + this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer), + ServiceQueryAnswerType_IP6Address, true, + pServiceQuery->m_pUserdata); + } + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _processAAnswer: FAILED to add IP6 " + "address (%s)!\n"), + p_pAAAAAnswer->m_IPAddress.toString().c_str());); + } + } + } + } + pServiceQuery = pServiceQuery->m_pNext; + } // while(service query) + } // else: No p_pAAAAAnswer + + return bResult; +} +#endif + +/* + PROBING +*/ + +/* + MDNSResponder::_updateProbeStatus + + Manages the (outgoing) probing process. + - If probing has not been started yet (ProbingStatus_NotStarted), the initial delay (see RFC + 6762) is determined and the process is started + - After timeout (of initial or subsequential delay) a probe message is send out for three + times. If the message has already been sent out three times, the probing has been successful + and is finished. + + Conflict management is handled in '_parseResponse ff.' + Tiebraking is handled in 'parseQuery ff.' +*/ +bool MDNSResponder::_updateProbeStatus(void) { + bool bResult = true; + + // + // Probe host domain + if (ProbingStatus_ReadyToStart == m_HostProbeInformation.m_ProbingStatus) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _updateProbeStatus: Starting host probing...\n"));); + + // First probe delay SHOULD be random 0-250 ms + m_HostProbeInformation.m_Timeout.reset(rand() % MDNS_PROBE_DELAY); + m_HostProbeInformation.m_ProbingStatus = ProbingStatus_InProgress; + } else if ((ProbingStatus_InProgress == m_HostProbeInformation.m_ProbingStatus) + && // Probing AND + (m_HostProbeInformation.m_Timeout.expired())) { // Time for next probe + if (MDNS_PROBE_COUNT > m_HostProbeInformation.m_u8SentCount) { // Send next probe + if ((bResult = _sendHostProbe())) { + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Did sent " + "host probe to all links \n\n"));); + } else { + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Did not " + "sent host probe to all links\n\n"));); + } + m_HostProbeInformation.m_Timeout.reset(MDNS_PROBE_DELAY); + ++m_HostProbeInformation.m_u8SentCount; + } else { // Probing finished + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _updateProbeStatus: Done host probing.\n"));); + m_HostProbeInformation.m_ProbingStatus = ProbingStatus_Done; + m_HostProbeInformation.m_Timeout.resetToNeverExpires(); + if (m_HostProbeInformation.m_fnHostProbeResultCallback) { + m_HostProbeInformation.m_fnHostProbeResultCallback(m_pcHostname, true); + } + + // Prepare to announce host + m_HostProbeInformation.m_u8SentCount = 0; + m_HostProbeInformation.m_Timeout.reset(MDNS_ANNOUNCE_DELAY); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _updateProbeStatus: Prepared host announcing.\n\n"));); + } + } // else: Probing already finished OR waiting for next time slot + else if ((ProbingStatus_Done == m_HostProbeInformation.m_ProbingStatus) + && (m_HostProbeInformation.m_Timeout.expired())) { + _announce(true, false); // Don't announce services here + + ++m_HostProbeInformation.m_u8SentCount; + + if (MDNS_ANNOUNCE_COUNT > m_HostProbeInformation.m_u8SentCount) { + m_HostProbeInformation.m_Timeout.reset(MDNS_ANNOUNCE_DELAY); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _updateProbeStatus: Announcing host (%d).\n\n"), + m_HostProbeInformation.m_u8SentCount);); + } else { + m_HostProbeInformation.m_Timeout.resetToNeverExpires(); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _updateProbeStatus: Done host announcing.\n\n"));); + } + } + + // + // Probe services + for (stcMDNSService* pService = m_pServices; ((bResult) && (pService)); + pService = pService->m_pNext) { + if (ProbingStatus_ReadyToStart + == pService->m_ProbeInformation.m_ProbingStatus) { // Ready to get started + pService->m_ProbeInformation.m_Timeout.reset( + MDNS_PROBE_DELAY); // More or equal than first probe for host domain + pService->m_ProbeInformation.m_ProbingStatus = ProbingStatus_InProgress; + } else if ((ProbingStatus_InProgress == pService->m_ProbeInformation.m_ProbingStatus) + && // Probing AND + (pService->m_ProbeInformation.m_Timeout.expired())) { // Time for next probe + if (MDNS_PROBE_COUNT + > pService->m_ProbeInformation.m_u8SentCount) { // Send next probe + if ((bResult = _sendServiceProbe(*pService))) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _updateProbeStatus: Did sent service probe to " + "all links " + "(%u)\n\n"), + (pService->m_ProbeInformation.m_u8SentCount + 1));); + } else { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _updateProbeStatus: Did not sent service probe " + "to all links" + "(%u)\n\n"), + (pService->m_ProbeInformation.m_u8SentCount + 1));); + } + pService->m_ProbeInformation.m_Timeout.reset(MDNS_PROBE_DELAY); + ++pService->m_ProbeInformation.m_u8SentCount; + } else { // Probing finished + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: " + "Done service probing %s.%s.%s\n\n"), + (pService->m_pcName ? : m_pcHostname), + pService->m_pcService, + pService->m_pcProtocol);); + pService->m_ProbeInformation.m_ProbingStatus = ProbingStatus_Done; + pService->m_ProbeInformation.m_Timeout.resetToNeverExpires(); + if (pService->m_ProbeInformation.m_fnServiceProbeResultCallback) { + pService->m_ProbeInformation.m_fnServiceProbeResultCallback( + pService->m_pcName, pService, true); + } + // Prepare to announce service + pService->m_ProbeInformation.m_u8SentCount = 0; + pService->m_ProbeInformation.m_Timeout.reset(MDNS_ANNOUNCE_DELAY); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR( + "[MDNSResponder] _updateProbeStatus: Prepared service announcing.\n\n"));); + } + } // else: Probing already finished OR waiting for next time slot + else if ((ProbingStatus_Done == pService->m_ProbeInformation.m_ProbingStatus) + && (pService->m_ProbeInformation.m_Timeout.expired())) { + _announceService(*pService); // Announce service + + ++pService->m_ProbeInformation.m_u8SentCount; + + if (MDNS_ANNOUNCE_COUNT > pService->m_ProbeInformation.m_u8SentCount) { + pService->m_ProbeInformation.m_Timeout.reset(MDNS_ANNOUNCE_DELAY); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _updateProbeStatus: Announcing service %s.%s.%s " + "(%d)\n\n"), + (pService->m_pcName ? : m_pcHostname), pService->m_pcService, + pService->m_pcProtocol, pService->m_ProbeInformation.m_u8SentCount);); + } else { + pService->m_ProbeInformation.m_Timeout.resetToNeverExpires(); + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: Done " + "service announcing for %s.%s.%s\n\n"), + (pService->m_pcName ? : m_pcHostname), + pService->m_pcService, pService->m_pcProtocol);); + } + } + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _updateProbeStatus: FAILED!\n\n")); + }); + return bResult; +} + +/* + MDNSResponder::_resetProbeStatus + + Resets the probe status. + If 'p_bRestart' is set, the status is set to ProbingStatus_NotStarted. Consequently, + when running 'updateProbeStatus' (which is done in every '_update' loop), the probing + process is restarted. +*/ +bool MDNSResponder::_resetProbeStatus(bool p_bRestart /*= true*/) { + m_HostProbeInformation.clear(false); + m_HostProbeInformation.m_ProbingStatus + = (p_bRestart ? ProbingStatus_ReadyToStart : ProbingStatus_Done); + + for (stcMDNSService* pService = m_pServices; pService; pService = pService->m_pNext) { + pService->m_ProbeInformation.clear(false); + pService->m_ProbeInformation.m_ProbingStatus + = (p_bRestart ? ProbingStatus_ReadyToStart : ProbingStatus_Done); + } + return true; +} + +/* + MDNSResponder::_hasProbesWaitingForAnswers +*/ +bool MDNSResponder::_hasProbesWaitingForAnswers(void) const { + bool bResult + = ((ProbingStatus_InProgress == m_HostProbeInformation.m_ProbingStatus) && // Probing + (0 < m_HostProbeInformation.m_u8SentCount)); // And really probing + + for (stcMDNSService* pService = m_pServices; ((!bResult) && (pService)); + pService = pService->m_pNext) { + bResult = ((ProbingStatus_InProgress == pService->m_ProbeInformation.m_ProbingStatus) + && // Probing + (0 < pService->m_ProbeInformation.m_u8SentCount)); // And really probing + } + return bResult; +} + +/* + MDNSResponder::_sendHostProbe + + Asks (probes) in the local network for the planned host domain + - (eg. esp8266.local) + + To allow 'tiebreaking' (see '_parseQuery'), the answers for these questions are delivered in + the 'knwon answers' section of the query. + Host domain: + - A/AAAA (eg. esp8266.esp -> 192.168.2.120) +*/ +bool MDNSResponder::_sendHostProbe(void) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendHostProbe (%s, %lu)\n"), + m_pcHostname, millis());); + + bool bResult = true; + + // Requests for host domain + stcMDNSSendParameter sendParameter; + sendParameter.m_bCacheFlush = false; // RFC 6762 10.2 + + sendParameter.m_pQuestions = new stcMDNS_RRQuestion; + if (((bResult = (0 != sendParameter.m_pQuestions))) + && ((bResult = _buildDomainForHost(m_pcHostname, + sendParameter.m_pQuestions->m_Header.m_Domain)))) { + // sendParameter.m_pQuestions->m_bUnicast = true; + sendParameter.m_pQuestions->m_Header.m_Attributes.m_u16Type = DNS_RRTYPE_ANY; + sendParameter.m_pQuestions->m_Header.m_Attributes.m_u16Class + = (0x8000 | DNS_RRCLASS_IN); // Unicast & INternet + + // Add known answers +#ifdef MDNS_IP4_SUPPORT + sendParameter.m_u8HostReplyMask |= ContentFlag_A; // Add A answer +#endif +#ifdef MDNS_IP6_SUPPORT + sendParameter.m_u8HostReplyMask |= ContentFlag_AAAA; // Add AAAA answer +#endif + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _sendHostProbe: FAILED to create host question!\n"));); + if (sendParameter.m_pQuestions) { + delete sendParameter.m_pQuestions; + sendParameter.m_pQuestions = 0; + } + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendHostProbe: FAILED!\n")); + }); + return ((bResult) && (_sendMDNSMessage(sendParameter))); +} + +/* + MDNSResponder::_sendServiceProbe + + Asks (probes) in the local network for the planned service instance domain + - (eg. MyESP._http._tcp.local). + + To allow 'tiebreaking' (see '_parseQuery'), the answers for these questions are delivered in + the 'knwon answers' section of the query. + Service domain: + - SRV (eg. MyESP._http._tcp.local -> 5000 esp8266.local) + - PTR NAME (eg. _http._tcp.local -> MyESP._http._tcp.local) (TODO: Check if needed, maybe + TXT is better) +*/ +bool MDNSResponder::_sendServiceProbe(stcMDNSService& p_rService) { + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendServiceProbe (%s.%s.%s, %lu)\n"), + (p_rService.m_pcName ? : m_pcHostname), p_rService.m_pcService, + p_rService.m_pcProtocol, millis());); + + bool bResult = true; + + // Requests for service instance domain + stcMDNSSendParameter sendParameter; + sendParameter.m_bCacheFlush = false; // RFC 6762 10.2 + + sendParameter.m_pQuestions = new stcMDNS_RRQuestion; + if (((bResult = (0 != sendParameter.m_pQuestions))) + && ((bResult = _buildDomainForService(p_rService, true, + sendParameter.m_pQuestions->m_Header.m_Domain)))) { + sendParameter.m_pQuestions->m_bUnicast = true; + sendParameter.m_pQuestions->m_Header.m_Attributes.m_u16Type = DNS_RRTYPE_ANY; + sendParameter.m_pQuestions->m_Header.m_Attributes.m_u16Class + = (0x8000 | DNS_RRCLASS_IN); // Unicast & INternet + + // Add known answers + p_rService.m_u8ReplyMask + = (ContentFlag_SRV | ContentFlag_PTR_NAME); // Add SRV and PTR NAME answers + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _sendServiceProbe: FAILED to create service question!\n"));); + if (sendParameter.m_pQuestions) { + delete sendParameter.m_pQuestions; + sendParameter.m_pQuestions = 0; + } + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendServiceProbe: FAILED!\n")); + }); + return ((bResult) && (_sendMDNSMessage(sendParameter))); +} + +/* + MDNSResponder::_cancelProbingForHost +*/ +bool MDNSResponder::_cancelProbingForHost(void) { + bool bResult = false; + + m_HostProbeInformation.clear(false); + // Send host notification + if (m_HostProbeInformation.m_fnHostProbeResultCallback) { + m_HostProbeInformation.m_fnHostProbeResultCallback(m_pcHostname, false); + + bResult = true; + } + + for (stcMDNSService* pService = m_pServices; ((!bResult) && (pService)); + pService = pService->m_pNext) { + bResult = _cancelProbingForService(*pService); + } + return bResult; +} + +/* + MDNSResponder::_cancelProbingForService +*/ +bool MDNSResponder::_cancelProbingForService(stcMDNSService& p_rService) { + bool bResult = false; + + p_rService.m_ProbeInformation.clear(false); + // Send notification + if (p_rService.m_ProbeInformation.m_fnServiceProbeResultCallback) { + p_rService.m_ProbeInformation.m_fnServiceProbeResultCallback(p_rService.m_pcName, + &p_rService, false); + bResult = true; + } + return bResult; +} + +/** + ANNOUNCING +*/ + +/* + MDNSResponder::_announce + + Announces the host domain: + - A/AAAA (eg. esp8266.local -> 192.168.2.120) + - PTR (eg. 192.168.2.120.in-addr.arpa -> esp8266.local) + + and all presented services: + - PTR_TYPE (_services._dns-sd._udp.local -> _http._tcp.local) + - PTR_NAME (eg. _http._tcp.local -> MyESP8266._http._tcp.local) + - SRV (eg. MyESP8266._http._tcp.local -> 5000 esp8266.local) + - TXT (eg. MyESP8266._http._tcp.local -> c#=1) + + Goodbye (Un-Announcing) for the host domain and all services is also handled here. + Goodbye messages are created by setting the TTL for the answer to 0, this happens + inside the '_writeXXXAnswer' procs via 'sendParameter.m_bUnannounce = true' +*/ +bool MDNSResponder::_announce(bool p_bAnnounce, bool p_bIncludeServices) { + bool bResult = false; + + stcMDNSSendParameter sendParameter; + if (ProbingStatus_Done == m_HostProbeInformation.m_ProbingStatus) { + bResult = true; + + sendParameter.m_bResponse + = true; // Announces are 'Unsolicited authoritative responses' + sendParameter.m_bAuthorative = true; + sendParameter.m_bUnannounce = !p_bAnnounce; // When unannouncing, the TTL is set to '0' + // while creating the answers + + // Announce host + sendParameter.m_u8HostReplyMask = 0; +#ifdef MDNS_IP4_SUPPORT + sendParameter.m_u8HostReplyMask |= ContentFlag_A; // A answer + sendParameter.m_u8HostReplyMask |= ContentFlag_PTR_IP4; // PTR_IP4 answer +#endif +#ifdef MDNS_IP6_SUPPORT + sendParameter.m_u8HostReplyMask |= ContentFlag_AAAA; // AAAA answer + sendParameter.m_u8HostReplyMask |= ContentFlag_PTR_IP6; // PTR_IP6 answer +#endif + + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _announce: Announcing host %s (content 0x%X)\n"), + m_pcHostname, sendParameter.m_u8HostReplyMask);); + + if (p_bIncludeServices) { + // Announce services (service type, name, SRV (location) and TXTs) + for (stcMDNSService* pService = m_pServices; ((bResult) && (pService)); + pService = pService->m_pNext) { + if (ProbingStatus_Done == pService->m_ProbeInformation.m_ProbingStatus) { + pService->m_u8ReplyMask = (ContentFlag_PTR_TYPE | ContentFlag_PTR_NAME + | ContentFlag_SRV | ContentFlag_TXT); + + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _announce: Announcing service %s.%s.%s (content " + "%u)\n"), + (pService->m_pcName ? : m_pcHostname), pService->m_pcService, + pService->m_pcProtocol, pService->m_u8ReplyMask);); + } + } + } + } + DEBUG_EX_ERR( + if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _announce: FAILED!\n")); + }); + return ((bResult) && (_sendMDNSMessage(sendParameter))); +} + +/* + MDNSResponder::_announceService +*/ +bool MDNSResponder::_announceService(stcMDNSService& p_rService, bool p_bAnnounce /*= true*/) { + bool bResult = false; + + stcMDNSSendParameter sendParameter; + if (ProbingStatus_Done == p_rService.m_ProbeInformation.m_ProbingStatus) { + sendParameter.m_bResponse + = true; // Announces are 'Unsolicited authoritative responses' + sendParameter.m_bAuthorative = true; + sendParameter.m_bUnannounce = !p_bAnnounce; // When unannouncing, the TTL is set to '0' + // while creating the answers + + // DON'T announce host + sendParameter.m_u8HostReplyMask = 0; + + // Announce services (service type, name, SRV (location) and TXTs) + p_rService.m_u8ReplyMask + = (ContentFlag_PTR_TYPE | ContentFlag_PTR_NAME | ContentFlag_SRV | ContentFlag_TXT); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _announceService: Announcing " + "service %s.%s.%s (content 0x%X)\n"), + (p_rService.m_pcName ? : m_pcHostname), + p_rService.m_pcService, p_rService.m_pcProtocol, + p_rService.m_u8ReplyMask);); + + bResult = true; + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _announceService: FAILED!\n")); + }); + return ((bResult) && (_sendMDNSMessage(sendParameter))); +} + +/** + SERVICE QUERY CACHE +*/ + +/* + MDNSResponder::_hasServiceQueriesWaitingForAnswers +*/ +bool MDNSResponder::_hasServiceQueriesWaitingForAnswers(void) const { + bool bOpenQueries = false; + + for (stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; pServiceQuery; + pServiceQuery = pServiceQuery->m_pNext) { + if (pServiceQuery->m_bAwaitingAnswers) { + bOpenQueries = true; + break; + } + } + return bOpenQueries; +} + +/* + MDNSResponder::_checkServiceQueryCache + + For any 'living' service query (m_bAwaitingAnswers == true) all available answers (their + components) are checked for topicality based on the stored reception time and the answers + TTL. When the components TTL is outlasted by more than 80%, a new question is generated, to + get updated information. When no update arrived (in time), the component is removed from the + answer (cache). + +*/ +bool MDNSResponder::_checkServiceQueryCache(void) { + bool bResult = true; + + DEBUG_EX_INFO(bool printedInfo = false;); + for (stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; ((bResult) && (pServiceQuery)); + pServiceQuery = pServiceQuery->m_pNext) { + // + // Resend dynamic service queries, if not already done often enough + if ((!pServiceQuery->m_bLegacyQuery) + && (MDNS_DYNAMIC_QUERY_RESEND_COUNT > pServiceQuery->m_u8SentCount) + && (pServiceQuery->m_ResendTimeout.expired())) { + if ((bResult = _sendMDNSServiceQuery(*pServiceQuery))) { + ++pServiceQuery->m_u8SentCount; + pServiceQuery->m_ResendTimeout.reset( + (MDNS_DYNAMIC_QUERY_RESEND_COUNT > pServiceQuery->m_u8SentCount) + ? (MDNS_DYNAMIC_QUERY_RESEND_DELAY * (pServiceQuery->m_u8SentCount - 1)) + : esp8266::polledTimeout::oneShotMs::neverExpires); + } + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: %s to resend service query!"), + (bResult ? "Succeeded" : "FAILED")); + printedInfo = true;); + } + + // + // Schedule updates for cached answers + if (pServiceQuery->m_bAwaitingAnswers) { + stcMDNSServiceQuery::stcAnswer* pSQAnswer = pServiceQuery->m_pAnswers; + while ((bResult) && (pSQAnswer)) { + stcMDNSServiceQuery::stcAnswer* pNextSQAnswer = pSQAnswer->m_pNext; + + // 1. level answer + if ((bResult) && (pSQAnswer->m_TTLServiceDomain.flagged())) { + if (!pSQAnswer->m_TTLServiceDomain.finalTimeoutLevel()) { + bResult = ((_sendMDNSServiceQuery(*pServiceQuery)) + && (pSQAnswer->m_TTLServiceDomain.restart())); + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: PTR update " + "scheduled for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" %s\n"), (bResult ? "OK" : "FAILURE")); + printedInfo = true;); + } else { + // Timed out! -> Delete + if (pServiceQuery->m_fnCallback) { + MDNSServiceInfo serviceInfo( + *this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer)); + pServiceQuery->m_fnCallback( + serviceInfo, + static_cast(ServiceQueryAnswerType_ServiceDomain), + false); + } + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: Will remove PTR " + "answer for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR("\n")); printedInfo = true;); + + bResult = pServiceQuery->removeAnswer(pSQAnswer); + pSQAnswer = 0; + continue; // Don't use this answer anymore + } + } // ServiceDomain flagged + + // 2. level answers + // HostDomain & Port (from SRV) + if ((bResult) && (pSQAnswer->m_TTLHostDomainAndPort.flagged())) { + if (!pSQAnswer->m_TTLHostDomainAndPort.finalTimeoutLevel()) { + bResult = ((_sendMDNSQuery(pSQAnswer->m_ServiceDomain, DNS_RRTYPE_SRV)) + && (pSQAnswer->m_TTLHostDomainAndPort.restart())); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: SRV update " + "scheduled for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" host domain and port %s\n"), + (bResult ? "OK" : "FAILURE")); + printedInfo = true;); + } else { + // Timed out! -> Delete + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: Will remove SRV " + "answer for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" host domain and port\n")); + printedInfo = true;); + // Delete + pSQAnswer->m_HostDomain.clear(); + pSQAnswer->releaseHostDomain(); + pSQAnswer->m_u16Port = 0; + pSQAnswer->m_TTLHostDomainAndPort.set(0); + uint32_t u32ContentFlags = ServiceQueryAnswerType_HostDomainAndPort; + // As the host domain is the base for the IP4- and IP6Address, remove + // these too +#ifdef MDNS_IP4_SUPPORT + pSQAnswer->releaseIP4Addresses(); + u32ContentFlags |= ServiceQueryAnswerType_IP4Address; +#endif +#ifdef MDNS_IP6_SUPPORT + pSQAnswer->releaseIP6Addresses(); + u32ContentFlags |= ServiceQueryAnswerType_IP6Address; +#endif + + // Remove content flags for deleted answer parts + pSQAnswer->m_u32ContentFlags &= ~u32ContentFlags; + if (pServiceQuery->m_fnCallback) { + MDNSServiceInfo serviceInfo( + *this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer)); + pServiceQuery->m_fnCallback( + serviceInfo, static_cast(u32ContentFlags), false); + } + } + } // HostDomainAndPort flagged + + // Txts (from TXT) + if ((bResult) && (pSQAnswer->m_TTLTxts.flagged())) { + if (!pSQAnswer->m_TTLTxts.finalTimeoutLevel()) { + bResult = ((_sendMDNSQuery(pSQAnswer->m_ServiceDomain, DNS_RRTYPE_TXT)) + && (pSQAnswer->m_TTLTxts.restart())); + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: TXT update " + "scheduled for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" TXTs %s\n"), + (bResult ? "OK" : "FAILURE")); + printedInfo = true;); + } else { + // Timed out! -> Delete + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: Will remove TXT " + "answer for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" TXTs\n")); + printedInfo = true;); + // Delete + pSQAnswer->m_Txts.clear(); + pSQAnswer->m_TTLTxts.set(0); + + // Remove content flags for deleted answer parts + pSQAnswer->m_u32ContentFlags &= ~ServiceQueryAnswerType_Txts; + + if (pServiceQuery->m_fnCallback) { + MDNSServiceInfo serviceInfo( + *this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer)); + pServiceQuery->m_fnCallback( + serviceInfo, + static_cast(ServiceQueryAnswerType_Txts), false); + } + } + } // TXTs flagged + + // 3. level answers +#ifdef MDNS_IP4_SUPPORT + // IP4Address (from A) + stcMDNSServiceQuery::stcAnswer::stcIP4Address* pIP4Address + = pSQAnswer->m_pIP4Addresses; + bool bAUpdateQuerySent = false; + while ((pIP4Address) && (bResult)) { + stcMDNSServiceQuery::stcAnswer::stcIP4Address* pNextIP4Address + = pIP4Address->m_pNext; // Get 'next' early, as 'current' may be + // deleted at the end... + + if (pIP4Address->m_TTL.flagged()) { + if (!pIP4Address->m_TTL.finalTimeoutLevel()) { // Needs update + if ((bAUpdateQuerySent) + || ((bResult + = _sendMDNSQuery(pSQAnswer->m_HostDomain, DNS_RRTYPE_A)))) { + pIP4Address->m_TTL.restart(); + bAUpdateQuerySent = true; + + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: IP4 " + "update scheduled for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P( + PSTR(" IP4 address (%s)\n"), + (pIP4Address->m_IPAddress.toString().c_str())); + printedInfo = true;); + } + } else { + // Timed out! -> Delete + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: Will remove IP4 " + "answer for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" IP4 address\n")); + printedInfo = true;); + pSQAnswer->removeIP4Address(pIP4Address); + if (!pSQAnswer->m_pIP4Addresses) // NO IP4 address left -> remove + // content flag + { + pSQAnswer->m_u32ContentFlags + &= ~ServiceQueryAnswerType_IP4Address; + } + // Notify client + if (pServiceQuery->m_fnCallback) { + MDNSServiceInfo serviceInfo( + *this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer)); + pServiceQuery->m_fnCallback( + serviceInfo, + static_cast(ServiceQueryAnswerType_IP4Address), + false); + } + } + } // IP4 flagged + + pIP4Address = pNextIP4Address; // Next + } // while +#endif +#ifdef MDNS_IP6_SUPPORT + // IP6Address (from AAAA) + stcMDNSServiceQuery::stcAnswer::stcIP6Address* pIP6Address + = pSQAnswer->m_pIP6Addresses; + bool bAAAAUpdateQuerySent = false; + while ((pIP6Address) && (bResult)) { + stcMDNSServiceQuery::stcAnswer::stcIP6Address* pNextIP6Address + = pIP6Address->m_pNext; // Get 'next' early, as 'current' may be + // deleted at the end... + + if (pIP6Address->m_TTL.flagged()) { + if (!pIP6Address->m_TTL.finalTimeoutLevel()) { // Needs update + if ((bAAAAUpdateQuerySent) + || ((bResult = _sendMDNSQuery(pSQAnswer->m_HostDomain, + DNS_RRTYPE_AAAA)))) { + pIP6Address->m_TTL.restart(); + bAAAAUpdateQuerySent = true; + + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: IP6 " + "update scheduled for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P( + PSTR(" IP6 address (%s)\n"), + (pIP6Address->m_IPAddress.toString().c_str())); + printedInfo = true;); + } + } else { + // Timed out! -> Delete + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _checkServiceQueryCache: Will remove " + "answer for ")); + _printRRDomain(pSQAnswer->m_ServiceDomain); + DEBUG_OUTPUT.printf_P(PSTR(" IP6Address\n")); + printedInfo = true;); + pSQAnswer->removeIP6Address(pIP6Address); + if (!pSQAnswer->m_pIP6Addresses) // NO IP6 address left -> remove + // content flag + { + pSQAnswer->m_u32ContentFlags + &= ~ServiceQueryAnswerType_IP6Address; + } + // Notify client + if (pServiceQuery->m_fnCallback) { + pServiceQuery->m_fnCallback( + this, (hMDNSServiceQuery)pServiceQuery, + pServiceQuery->indexOfAnswer(pSQAnswer), + ServiceQueryAnswerType_IP6Address, false, + pServiceQuery->m_pUserdata); + } + } + } // IP6 flagged + + pIP6Address = pNextIP6Address; // Next + } // while +#endif + pSQAnswer = pNextSQAnswer; + } + } + } + DEBUG_EX_INFO(if (printedInfo) { + DEBUG_OUTPUT.printf_P(PSTR("\n")); + }); + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _checkServiceQueryCache: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_replyMaskForHost + + Determines the relevant host answers for the given question. + - A question for the hostname (eg. esp8266.local) will result in an A/AAAA (eg. + 192.168.2.129) reply. + - A question for the reverse IP address (eg. 192-168.2.120.inarpa.arpa) will result in an + PTR_IP4 (eg. esp8266.local) reply. + + In addition, a full name match (question domain == host domain) is marked. +*/ +uint8_t MDNSResponder::_replyMaskForHost(const MDNSResponder::stcMDNS_RRHeader& p_RRHeader, + bool* p_pbFullNameMatch /*= 0*/) const { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _replyMaskForHost\n"));); + + uint8_t u8ReplyMask = 0; + (p_pbFullNameMatch ? * p_pbFullNameMatch = false : 0); + + if ((DNS_RRCLASS_IN == p_RRHeader.m_Attributes.m_u16Class) + || (DNS_RRCLASS_ANY == p_RRHeader.m_Attributes.m_u16Class)) { + if ((DNS_RRTYPE_PTR == p_RRHeader.m_Attributes.m_u16Type) + || (DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type)) { + // PTR request +#ifdef MDNS_IP4_SUPPORT + stcMDNS_RRDomain reverseIP4Domain; + for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next) { + if (netif_is_up(pNetIf)) { + if ((_buildDomainForReverseIP4(pNetIf->ip_addr, reverseIP4Domain)) + && (p_RRHeader.m_Domain == reverseIP4Domain)) { + // Reverse domain match + u8ReplyMask |= ContentFlag_PTR_IP4; + } + } + } +#endif +#ifdef MDNS_IP6_SUPPORT + // TODO +#endif + } // Address qeuest + + stcMDNS_RRDomain hostDomain; + if ((_buildDomainForHost(m_pcHostname, hostDomain)) + && (p_RRHeader.m_Domain == hostDomain)) { // Host domain match + (p_pbFullNameMatch ? (*p_pbFullNameMatch = true) : (0)); + +#ifdef MDNS_IP4_SUPPORT + if ((DNS_RRTYPE_A == p_RRHeader.m_Attributes.m_u16Type) + || (DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type)) { + // IP4 address request + u8ReplyMask |= ContentFlag_A; + } +#endif +#ifdef MDNS_IP6_SUPPORT + if ((DNS_RRTYPE_AAAA == p_RRHeader.m_Attributes.m_u16Type) + || (DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type)) { + // IP6 address request + u8ReplyMask |= ContentFlag_AAAA; + } +#endif + } + } else { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _replyMaskForHost: INVALID + // RR-class (0x%04X)!\n"), p_RRHeader.m_Attributes.m_u16Class);); + } + DEBUG_EX_INFO(if (u8ReplyMask) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _replyMaskForHost: 0x%X\n"), u8ReplyMask); + }); + return u8ReplyMask; +} + +/* + MDNSResponder::_replyMaskForService + + Determines the relevant service answers for the given question + - A PTR dns-sd service enum question (_services.dns-sd._udp.local) will result into an + PTR_TYPE (eg. _http._tcp.local) answer + - A PTR service type question (eg. _http._tcp.local) will result into an PTR_NAME (eg. + MyESP._http._tcp.local) answer + - A PTR service name question (eg. MyESP._http._tcp.local) will result into an PTR_NAME (eg. + MyESP._http._tcp.local) answer + - A SRV service name question (eg. MyESP._http._tcp.local) will result into an SRV (eg. 5000 + MyESP.local) answer + - A TXT service name question (eg. MyESP._http._tcp.local) will result into an TXT (eg. + c#=1) answer + + In addition, a full name match (question domain == service instance domain) is marked. +*/ +uint8_t MDNSResponder::_replyMaskForService(const MDNSResponder::stcMDNS_RRHeader& p_RRHeader, + const MDNSResponder::stcMDNSService& p_Service, + bool* p_pbFullNameMatch /*= 0*/) const { + uint8_t u8ReplyMask = 0; + (p_pbFullNameMatch ? * p_pbFullNameMatch = false : 0); + + if ((DNS_RRCLASS_IN == p_RRHeader.m_Attributes.m_u16Class) + || (DNS_RRCLASS_ANY == p_RRHeader.m_Attributes.m_u16Class)) { + stcMDNS_RRDomain DNSSDDomain; + if ((_buildDomainForDNSSD(DNSSDDomain)) && // _services._dns-sd._udp.local + (p_RRHeader.m_Domain == DNSSDDomain) + && ((DNS_RRTYPE_PTR == p_RRHeader.m_Attributes.m_u16Type) + || (DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type))) { + // Common service info requested + u8ReplyMask |= ContentFlag_PTR_TYPE; + } + + stcMDNS_RRDomain serviceDomain; + if ((_buildDomainForService(p_Service, false, serviceDomain)) + && // eg. _http._tcp.local + (p_RRHeader.m_Domain == serviceDomain) + && ((DNS_RRTYPE_PTR == p_RRHeader.m_Attributes.m_u16Type) + || (DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type))) { + // Special service info requested + u8ReplyMask |= ContentFlag_PTR_NAME; + } + + if ((_buildDomainForService(p_Service, true, serviceDomain)) + && // eg. MyESP._http._tcp.local + (p_RRHeader.m_Domain == serviceDomain)) { + (p_pbFullNameMatch ? (*p_pbFullNameMatch = true) : (0)); + + if ((DNS_RRTYPE_SRV == p_RRHeader.m_Attributes.m_u16Type) + || (DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type)) { + // Instance info SRV requested + u8ReplyMask |= ContentFlag_SRV; + } + if ((DNS_RRTYPE_TXT == p_RRHeader.m_Attributes.m_u16Type) + || (DNS_RRTYPE_ANY == p_RRHeader.m_Attributes.m_u16Type)) { + // Instance info TXT requested + u8ReplyMask |= ContentFlag_TXT; + } + } + } else { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _replyMaskForService: + // INVALID RR-class (0x%04X)!\n"), p_RRHeader.m_Attributes.m_u16Class);); + } + DEBUG_EX_INFO(if (u8ReplyMask) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _replyMaskForService(%s.%s.%s): 0x%X\n"), + p_Service.m_pcName, p_Service.m_pcService, p_Service.m_pcProtocol, + u8ReplyMask); + }); + return u8ReplyMask; +} + +} // namespace MDNSImplementation + +} // namespace esp8266 diff --git a/libraries/LEAmDNS/src/LEAmDNS_Helpers.cpp b/libraries/LEAmDNS/src/LEAmDNS_Helpers.cpp new file mode 100644 index 00000000..39ccf847 --- /dev/null +++ b/libraries/LEAmDNS/src/LEAmDNS_Helpers.cpp @@ -0,0 +1,671 @@ +/* + LEAmDNS_Helpers.cpp + + License (MIT license): + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#include +#include // strrstr() + +#include "ESP8266mDNS.h" +#include "LEAmDNS_lwIPdefs.h" +#include "LEAmDNS_Priv.h" + +namespace esp8266 { + +/* + LEAmDNS +*/ +namespace MDNSImplementation { + +/** + HELPERS +*/ + +/* + MDNSResponder::indexDomain (static) + + Updates the given domain 'p_rpcHostname' by appending a delimiter and an index number. + + If the given domain already hasa numeric index (after the given delimiter), this index + incremented. If not, the delimiter and index '2' is added. + + If 'p_rpcHostname' is empty (==0), the given default name 'p_pcDefaultHostname' is used, + if no default is given, 'esp8266' is used. + +*/ +/*static*/ bool MDNSResponder::indexDomain(char*& p_rpcDomain, + const char* p_pcDivider /*= "-"*/, + const char* p_pcDefaultDomain /*= 0*/) { + bool bResult = false; + + // Ensure a divider exists; use '-' as default + const char* pcDivider = (p_pcDivider ? : "-"); + + if (p_rpcDomain) { + const char* pFoundDivider = strrstr(p_rpcDomain, pcDivider); + if (pFoundDivider) { // maybe already extended + char* pEnd = 0; + unsigned long ulIndex = strtoul((pFoundDivider + strlen(pcDivider)), &pEnd, 10); + if ((ulIndex) && ((pEnd - p_rpcDomain) == (ptrdiff_t)strlen(p_rpcDomain)) + && (!*pEnd)) { // Valid (old) index found + char acIndexBuffer[16]; + sprintf(acIndexBuffer, "%lu", (++ulIndex)); + size_t stLength = ((pFoundDivider - p_rpcDomain + strlen(pcDivider)) + + strlen(acIndexBuffer) + 1); + char* pNewHostname = new char[stLength]; + if (pNewHostname) { + memcpy(pNewHostname, p_rpcDomain, + (pFoundDivider - p_rpcDomain + strlen(pcDivider))); + pNewHostname[pFoundDivider - p_rpcDomain + strlen(pcDivider)] = 0; + strcat(pNewHostname, acIndexBuffer); + + delete[] p_rpcDomain; + p_rpcDomain = pNewHostname; + + bResult = true; + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.println( + F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!"));); + } + } else { + pFoundDivider = 0; // Flag the need to (base) extend the hostname + } + } + + if (!pFoundDivider) // not yet extended (or failed to increment extension) -> start + // indexing + { + size_t stLength = strlen(p_rpcDomain) + + (strlen(pcDivider) + 1 + 1); // Name + Divider + '2' + '\0' + char* pNewHostname = new char[stLength]; + if (pNewHostname) { + sprintf(pNewHostname, "%s%s2", p_rpcDomain, pcDivider); + + delete[] p_rpcDomain; + p_rpcDomain = pNewHostname; + + bResult = true; + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.println( + F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!"));); + } + } + } else { + // No given host domain, use base or default + const char* cpcDefaultName = (p_pcDefaultDomain ? : "esp8266"); + + size_t stLength = strlen(cpcDefaultName) + 1; // '\0' + p_rpcDomain = new char[stLength]; + if (p_rpcDomain) { + strncpy(p_rpcDomain, cpcDefaultName, stLength); + bResult = true; + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.println( + F("[MDNSResponder] indexDomain: FAILED to alloc new hostname!"));); + } + } + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] indexDomain: %s\n"), p_rpcDomain);); + return bResult; +} + +/* + UDP CONTEXT +*/ + +bool MDNSResponder::_callProcess(void) { + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf("[MDNSResponder] _callProcess (%lu, triggered by: %s)\n", millis(), + IPAddress(m_pUDPContext->getRemoteAddress()).toString().c_str());); + + return _process(false); +} + +/* + MDNSResponder::_allocUDPContext + + (Re-)Creates the one-and-only UDP context for the MDNS responder. + The context is added to the 'multicast'-group and listens to the MDNS port (5353). + The travel-distance for multicast messages is set to 1 (local, via MDNS_MULTICAST_TTL). + Messages are received via the MDNSResponder '_update' function. CAUTION: This function + is called from the WiFi stack side of the ESP stack system. + +*/ +bool MDNSResponder::_allocUDPContext(void) { + DEBUG_EX_INFO(DEBUG_OUTPUT.println("[MDNSResponder] _allocUDPContext");); + + _releaseUDPContext(); + _joinMulticastGroups(); + + m_pUDPContext = new UdpContext; + m_pUDPContext->ref(); + + if (m_pUDPContext->listen(IP4_ADDR_ANY, DNS_MQUERY_PORT)) { + m_pUDPContext->setMulticastTTL(MDNS_MULTICAST_TTL); + m_pUDPContext->onRx(std::bind(&MDNSResponder::_callProcess, this)); + } else { + return false; + } + + return true; +} + +/* + MDNSResponder::_releaseUDPContext +*/ +bool MDNSResponder::_releaseUDPContext(void) { + if (m_pUDPContext) { + m_pUDPContext->unref(); + m_pUDPContext = 0; + _leaveMulticastGroups(); + } + return true; +} + +/* + SERVICE QUERY +*/ + +/* + MDNSResponder::_allocServiceQuery +*/ +MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_allocServiceQuery(void) { + stcMDNSServiceQuery* pServiceQuery = new stcMDNSServiceQuery; + if (pServiceQuery) { + // Link to query list + pServiceQuery->m_pNext = m_pServiceQueries; + m_pServiceQueries = pServiceQuery; + } + return m_pServiceQueries; +} + +/* + MDNSResponder::_removeServiceQuery +*/ +bool MDNSResponder::_removeServiceQuery(MDNSResponder::stcMDNSServiceQuery* p_pServiceQuery) { + bool bResult = false; + + if (p_pServiceQuery) { + stcMDNSServiceQuery* pPred = m_pServiceQueries; + while ((pPred) && (pPred->m_pNext != p_pServiceQuery)) { + pPred = pPred->m_pNext; + } + if (pPred) { + pPred->m_pNext = p_pServiceQuery->m_pNext; + delete p_pServiceQuery; + bResult = true; + } else { // No predecessor + if (m_pServiceQueries == p_pServiceQuery) { + m_pServiceQueries = p_pServiceQuery->m_pNext; + delete p_pServiceQuery; + bResult = true; + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.println( + "[MDNSResponder] _releaseServiceQuery: INVALID service query!");); + } + } + } + return bResult; +} + +/* + MDNSResponder::_removeLegacyServiceQuery +*/ +bool MDNSResponder::_removeLegacyServiceQuery(void) { + stcMDNSServiceQuery* pLegacyServiceQuery = _findLegacyServiceQuery(); + return (pLegacyServiceQuery ? _removeServiceQuery(pLegacyServiceQuery) : true); +} + +/* + MDNSResponder::_findServiceQuery + + 'Convert' hMDNSServiceQuery to stcMDNSServiceQuery* (ensure existence) + +*/ +MDNSResponder::stcMDNSServiceQuery* +MDNSResponder::_findServiceQuery(MDNSResponder::hMDNSServiceQuery p_hServiceQuery) { + stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; + while (pServiceQuery) { + if ((hMDNSServiceQuery)pServiceQuery == p_hServiceQuery) { + break; + } + pServiceQuery = pServiceQuery->m_pNext; + } + return pServiceQuery; +} + +/* + MDNSResponder::_findLegacyServiceQuery +*/ +MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findLegacyServiceQuery(void) { + stcMDNSServiceQuery* pServiceQuery = m_pServiceQueries; + while (pServiceQuery) { + if (pServiceQuery->m_bLegacyQuery) { + break; + } + pServiceQuery = pServiceQuery->m_pNext; + } + return pServiceQuery; +} + +/* + MDNSResponder::_releaseServiceQueries +*/ +bool MDNSResponder::_releaseServiceQueries(void) { + while (m_pServiceQueries) { + stcMDNSServiceQuery* pNext = m_pServiceQueries->m_pNext; + delete m_pServiceQueries; + m_pServiceQueries = pNext; + } + return true; +} + +/* + MDNSResponder::_findNextServiceQueryByServiceType +*/ +MDNSResponder::stcMDNSServiceQuery* MDNSResponder::_findNextServiceQueryByServiceType( + const stcMDNS_RRDomain& p_ServiceTypeDomain, const stcMDNSServiceQuery* p_pPrevServiceQuery) { + stcMDNSServiceQuery* pMatchingServiceQuery = 0; + + stcMDNSServiceQuery* pServiceQuery + = (p_pPrevServiceQuery ? p_pPrevServiceQuery->m_pNext : m_pServiceQueries); + while (pServiceQuery) { + if (p_ServiceTypeDomain == pServiceQuery->m_ServiceTypeDomain) { + pMatchingServiceQuery = pServiceQuery; + break; + } + pServiceQuery = pServiceQuery->m_pNext; + } + return pMatchingServiceQuery; +} + +/* + HOSTNAME +*/ + +/* + MDNSResponder::_setHostname +*/ +bool MDNSResponder::_setHostname(const char* p_pcHostname) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _allocHostname (%s)\n"), + // p_pcHostname);); + + bool bResult = false; + + _releaseHostname(); + + size_t stLength = 0; + if ((p_pcHostname) + && (MDNS_DOMAIN_LABEL_MAXLENGTH + >= (stLength = strlen(p_pcHostname)))) { // char max size for a single label + // Copy in hostname characters as lowercase + if ((bResult = (0 != (m_pcHostname = new char[stLength + 1])))) { +#ifdef MDNS_FORCE_LOWERCASE_HOSTNAME + size_t i = 0; + for (; i < stLength; ++i) { + m_pcHostname[i] + = (isupper(p_pcHostname[i]) ? tolower(p_pcHostname[i]) : p_pcHostname[i]); + } + m_pcHostname[i] = 0; +#else + strncpy(m_pcHostname, p_pcHostname, (stLength + 1)); +#endif + } + } + return bResult; +} + +/* + MDNSResponder::_releaseHostname +*/ +bool MDNSResponder::_releaseHostname(void) { + if (m_pcHostname) { + delete[] m_pcHostname; + m_pcHostname = 0; + } + return true; +} + +/* + SERVICE +*/ + +/* + MDNSResponder::_allocService +*/ +MDNSResponder::stcMDNSService* MDNSResponder::_allocService(const char* p_pcName, + const char* p_pcService, + const char* p_pcProtocol, + uint16_t p_u16Port) { + stcMDNSService* pService = 0; + if (((!p_pcName) || (MDNS_DOMAIN_LABEL_MAXLENGTH >= strlen(p_pcName))) && (p_pcService) + && (MDNS_SERVICE_NAME_LENGTH >= strlen(p_pcService)) && (p_pcProtocol) + && (MDNS_SERVICE_PROTOCOL_LENGTH >= strlen(p_pcProtocol)) && (p_u16Port) + && (0 != (pService = new stcMDNSService)) + && (pService->setName(p_pcName ? : m_pcHostname)) && (pService->setService(p_pcService)) + && (pService->setProtocol(p_pcProtocol))) { + pService->m_bAutoName = (0 == p_pcName); + pService->m_u16Port = p_u16Port; + + // Add to list (or start list) + pService->m_pNext = m_pServices; + m_pServices = pService; + } + return pService; +} + +/* + MDNSResponder::_releaseService +*/ +bool MDNSResponder::_releaseService(MDNSResponder::stcMDNSService* p_pService) { + bool bResult = false; + + if (p_pService) { + stcMDNSService* pPred = m_pServices; + while ((pPred) && (pPred->m_pNext != p_pService)) { + pPred = pPred->m_pNext; + } + if (pPred) { + pPred->m_pNext = p_pService->m_pNext; + delete p_pService; + bResult = true; + } else { // No predecessor + if (m_pServices == p_pService) { + m_pServices = p_pService->m_pNext; + delete p_pService; + bResult = true; + } else { + DEBUG_EX_ERR( + DEBUG_OUTPUT.println("[MDNSResponder] _releaseService: INVALID service!");); + } + } + } + return bResult; +} + +/* + MDNSResponder::_releaseServices +*/ +bool MDNSResponder::_releaseServices(void) { + stcMDNSService* pService = m_pServices; + while (pService) { + _releaseService(pService); + pService = m_pServices; + } + return true; +} + +/* + MDNSResponder::_findService +*/ +MDNSResponder::stcMDNSService* MDNSResponder::_findService(const char* p_pcName, + const char* p_pcService, + const char* p_pcProtocol) { + stcMDNSService* pService = m_pServices; + while (pService) { + if ((0 == strcmp(pService->m_pcName, p_pcName)) + && (0 == strcmp(pService->m_pcService, p_pcService)) + && (0 == strcmp(pService->m_pcProtocol, p_pcProtocol))) { + break; + } + pService = pService->m_pNext; + } + return pService; +} + +/* + MDNSResponder::_findService +*/ +MDNSResponder::stcMDNSService* +MDNSResponder::_findService(const MDNSResponder::hMDNSService p_hService) { + stcMDNSService* pService = m_pServices; + while (pService) { + if (p_hService == (hMDNSService)pService) { + break; + } + pService = pService->m_pNext; + } + return pService; +} + +/* + SERVICE TXT +*/ + +/* + MDNSResponder::_allocServiceTxt +*/ +MDNSResponder::stcMDNSServiceTxt* +MDNSResponder::_allocServiceTxt(MDNSResponder::stcMDNSService* p_pService, const char* p_pcKey, + const char* p_pcValue, bool p_bTemp) { + stcMDNSServiceTxt* pTxt = 0; + + if ((p_pService) && (p_pcKey) + && (MDNS_SERVICE_TXT_MAXLENGTH > (p_pService->m_Txts.length() + 1 + // Length byte + (p_pcKey ? strlen(p_pcKey) : 0) + 1 + // '=' + (p_pcValue ? strlen(p_pcValue) : 0)))) { + pTxt = new stcMDNSServiceTxt; + if (pTxt) { + size_t stLength = (p_pcKey ? strlen(p_pcKey) : 0); + pTxt->m_pcKey = new char[stLength + 1]; + if (pTxt->m_pcKey) { + strncpy(pTxt->m_pcKey, p_pcKey, stLength); + pTxt->m_pcKey[stLength] = 0; + } + + if (p_pcValue) { + stLength = (p_pcValue ? strlen(p_pcValue) : 0); + pTxt->m_pcValue = new char[stLength + 1]; + if (pTxt->m_pcValue) { + strncpy(pTxt->m_pcValue, p_pcValue, stLength); + pTxt->m_pcValue[stLength] = 0; + } + } + pTxt->m_bTemp = p_bTemp; + + // Add to list (or start list) + p_pService->m_Txts.add(pTxt); + } + } + return pTxt; +} + +/* + MDNSResponder::_releaseServiceTxt +*/ +bool MDNSResponder::_releaseServiceTxt(MDNSResponder::stcMDNSService* p_pService, + MDNSResponder::stcMDNSServiceTxt* p_pTxt) { + return ((p_pService) && (p_pTxt) && (p_pService->m_Txts.remove(p_pTxt))); +} + +/* + MDNSResponder::_updateServiceTxt +*/ +MDNSResponder::stcMDNSServiceTxt* +MDNSResponder::_updateServiceTxt(MDNSResponder::stcMDNSService* p_pService, + MDNSResponder::stcMDNSServiceTxt* p_pTxt, + const char* p_pcValue, bool p_bTemp) { + if ((p_pService) && (p_pTxt) + && (MDNS_SERVICE_TXT_MAXLENGTH + > (p_pService->m_Txts.length() - (p_pTxt->m_pcValue ? strlen(p_pTxt->m_pcValue) : 0) + + (p_pcValue ? strlen(p_pcValue) : 0)))) { + p_pTxt->update(p_pcValue); + p_pTxt->m_bTemp = p_bTemp; + } + return p_pTxt; +} + +/* + MDNSResponder::_findServiceTxt +*/ +MDNSResponder::stcMDNSServiceTxt* +MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService, const char* p_pcKey) { + return (p_pService ? p_pService->m_Txts.find(p_pcKey) : 0); +} + +/* + MDNSResponder::_findServiceTxt +*/ +MDNSResponder::stcMDNSServiceTxt* +MDNSResponder::_findServiceTxt(MDNSResponder::stcMDNSService* p_pService, const hMDNSTxt p_hTxt) { + return (((p_pService) && (p_hTxt)) ? p_pService->m_Txts.find((stcMDNSServiceTxt*)p_hTxt) + : 0); +} + +/* + MDNSResponder::_addServiceTxt +*/ +MDNSResponder::stcMDNSServiceTxt* +MDNSResponder::_addServiceTxt(MDNSResponder::stcMDNSService* p_pService, const char* p_pcKey, + const char* p_pcValue, bool p_bTemp) { + stcMDNSServiceTxt* pResult = 0; + + if ((p_pService) && (p_pcKey) && (strlen(p_pcKey))) { + stcMDNSServiceTxt* pTxt = p_pService->m_Txts.find(p_pcKey); + if (pTxt) { + pResult = _updateServiceTxt(p_pService, pTxt, p_pcValue, p_bTemp); + } else { + pResult = _allocServiceTxt(p_pService, p_pcKey, p_pcValue, p_bTemp); + } + } + return pResult; +} + +MDNSResponder::stcMDNSServiceTxt* +MDNSResponder::_answerKeyValue(const hMDNSServiceQuery p_hServiceQuery, + const uint32_t p_u32AnswerIndex) { + stcMDNSServiceQuery* pServiceQuery = _findServiceQuery(p_hServiceQuery); + stcMDNSServiceQuery::stcAnswer* pSQAnswer + = (pServiceQuery ? pServiceQuery->answerAtIndex(p_u32AnswerIndex) : 0); + // Fill m_pcTxts (if not already done) + return (pSQAnswer) ? pSQAnswer->m_Txts.m_pTxts : 0; +} + +/* + MDNSResponder::_collectServiceTxts +*/ +bool MDNSResponder::_collectServiceTxts(MDNSResponder::stcMDNSService& p_rService) { + // Call Dynamic service callbacks + if (m_fnServiceTxtCallback) { + m_fnServiceTxtCallback((hMDNSService)&p_rService); + } + if (p_rService.m_fnTxtCallback) { + p_rService.m_fnTxtCallback((hMDNSService)&p_rService); + } + return true; +} + +/* + MDNSResponder::_releaseTempServiceTxts +*/ +bool MDNSResponder::_releaseTempServiceTxts(MDNSResponder::stcMDNSService& p_rService) { + return (p_rService.m_Txts.removeTempTxts()); +} + +/* + MISC +*/ + +#ifdef DEBUG_ESP_MDNS_RESPONDER +/* + MDNSResponder::_printRRDomain +*/ +bool MDNSResponder::_printRRDomain(const MDNSResponder::stcMDNS_RRDomain& p_RRDomain) const { + // DEBUG_OUTPUT.printf_P(PSTR("Domain: ")); + + const char* pCursor = p_RRDomain.m_acName; + uint8_t u8Length = *pCursor++; + if (u8Length) { + while (u8Length) { + for (uint8_t u = 0; u < u8Length; ++u) { + DEBUG_OUTPUT.printf_P(PSTR("%c"), *(pCursor++)); + } + u8Length = *pCursor++; + if (u8Length) { + DEBUG_OUTPUT.printf_P(PSTR(".")); + } + } + } else { // empty domain + DEBUG_OUTPUT.printf_P(PSTR("-empty-")); + } + // DEBUG_OUTPUT.printf_P(PSTR("\n")); + + return true; +} + +/* + MDNSResponder::_printRRAnswer +*/ +bool MDNSResponder::_printRRAnswer(const MDNSResponder::stcMDNS_RRAnswer& p_RRAnswer) const { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] RRAnswer: ")); + _printRRDomain(p_RRAnswer.m_Header.m_Domain); + DEBUG_OUTPUT.printf_P(PSTR(" Type:0x%04X Class:0x%04X TTL:%u, "), + p_RRAnswer.m_Header.m_Attributes.m_u16Type, + p_RRAnswer.m_Header.m_Attributes.m_u16Class, p_RRAnswer.m_u32TTL); + switch (p_RRAnswer.m_Header.m_Attributes.m_u16Type + & (~0x8000)) { // Topmost bit might carry 'cache flush' flag +#ifdef MDNS_IP4_SUPPORT + case DNS_RRTYPE_A: + DEBUG_OUTPUT.printf_P( + PSTR("A IP:%s"), + ((const stcMDNS_RRAnswerA*)&p_RRAnswer)->m_IPAddress.toString().c_str()); + break; +#endif + case DNS_RRTYPE_PTR: + DEBUG_OUTPUT.printf_P(PSTR("PTR ")); + _printRRDomain(((const stcMDNS_RRAnswerPTR*)&p_RRAnswer)->m_PTRDomain); + break; + case DNS_RRTYPE_TXT: { + size_t stTxtLength = ((const stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_strLength(); + char* pTxts = new char[stTxtLength]; + if (pTxts) { + ((/*const c_str()!!*/ stcMDNS_RRAnswerTXT*)&p_RRAnswer)->m_Txts.c_str(pTxts); + DEBUG_OUTPUT.printf_P(PSTR("TXT(%zu) %s"), stTxtLength, pTxts); + delete[] pTxts; + } + break; + } +#ifdef MDNS_IP6_SUPPORT + case DNS_RRTYPE_AAAA: + DEBUG_OUTPUT.printf_P( + PSTR("AAAA IP:%s"), + ((stcMDNS_RRAnswerA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str()); + break; +#endif + case DNS_RRTYPE_SRV: + DEBUG_OUTPUT.printf_P(PSTR("SRV Port:%u "), + ((const stcMDNS_RRAnswerSRV*)&p_RRAnswer)->m_u16Port); + _printRRDomain(((const stcMDNS_RRAnswerSRV*)&p_RRAnswer)->m_SRVDomain); + break; + default: + DEBUG_OUTPUT.printf_P(PSTR("generic ")); + break; + } + DEBUG_OUTPUT.printf_P(PSTR("\n")); + + return true; +} +#endif + +} // namespace MDNSImplementation + +} // namespace esp8266 diff --git a/libraries/LEAmDNS/src/LEAmDNS_Priv.h b/libraries/LEAmDNS/src/LEAmDNS_Priv.h new file mode 100644 index 00000000..e59b70ec --- /dev/null +++ b/libraries/LEAmDNS/src/LEAmDNS_Priv.h @@ -0,0 +1,190 @@ +/* + LEAmDNS_Priv.h + + License (MIT license): + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#ifndef MDNS_PRIV_H +#define MDNS_PRIV_H + +namespace esp8266 { + +/* + LEAmDNS +*/ + +namespace MDNSImplementation { + +// Enable class debug functions +#define ESP_8266_MDNS_INCLUDE +//#define DEBUG_ESP_MDNS_RESPONDER + +#if !defined(DEBUG_ESP_MDNS_RESPONDER) && defined(DEBUG_ESP_MDNS) +#define DEBUG_ESP_MDNS_RESPONDER +#endif + +// +// If ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE is defined, the mDNS responder ignores a successful +// probing This allows to drive the responder in a environment, where 'update()' isn't called in the +// loop +//#define ENABLE_ESP_MDNS_RESPONDER_PASSIV_MODE + +// Enable/disable debug trace macros +#if defined(DEBUG_ESP_PORT) && defined(DEBUG_ESP_MDNS_RESPONDER) +#define DEBUG_ESP_MDNS_INFO +#define DEBUG_ESP_MDNS_ERR +#define DEBUG_ESP_MDNS_TX +#define DEBUG_ESP_MDNS_RX +#endif + +#ifdef DEBUG_ESP_MDNS_RESPONDER +#ifdef DEBUG_ESP_MDNS_INFO +#define DEBUG_EX_INFO(A) A +#else +#define DEBUG_EX_INFO(A) +#endif +#ifdef DEBUG_ESP_MDNS_ERR +#define DEBUG_EX_ERR(A) A +#else +#define DEBUG_EX_ERR(A) +#endif +#ifdef DEBUG_ESP_MDNS_TX +#define DEBUG_EX_TX(A) A +#else +#define DEBUG_EX_TX(A) +#endif +#ifdef DEBUG_ESP_MDNS_RX +#define DEBUG_EX_RX(A) A +#else +#define DEBUG_EX_RX(A) +#endif + +#ifdef DEBUG_ESP_PORT +#define DEBUG_OUTPUT DEBUG_ESP_PORT +#else +#define DEBUG_OUTPUT Serial +#endif +#else +#define DEBUG_EX_INFO(A) \ + do \ + { \ + (void)0; \ + } while (0) +#define DEBUG_EX_ERR(A) \ + do \ + { \ + (void)0; \ + } while (0) +#define DEBUG_EX_TX(A) \ + do \ + { \ + (void)0; \ + } while (0) +#define DEBUG_EX_RX(A) \ + do \ + { \ + (void)0; \ + } while (0) +#endif + +/* already defined in lwIP ('lwip/prot/dns.h') + #ifdef MDNS_IP4_SUPPORT + #define DNS_MQUERY_IPV4_GROUP_INIT (IPAddress(224, 0, 0, 251)) // ip_addr_t + v4group = DNS_MQUERY_IPV4_GROUP_INIT #endif #ifdef MDNS_IP6_SUPPORT #define + DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB) // ip_addr_t v6group = + DNS_MQUERY_IPV6_GROUP_INIT #endif*/ +//#define MDNS_MULTICAST_PORT 5353 + +/* + This is NOT the TTL (Time-To-Live) for MDNS records, but the + subnet level distance MDNS records should travel. + 1 sets the subnet distance to 'local', which is default for MDNS. + (Btw.: 255 would set it to 'as far as possible' -> internet) + + However, RFC 3171 seems to force 255 instead +*/ +#define MDNS_MULTICAST_TTL 255 /*1*/ + +/* + This is the MDNS record TTL + Host level records are set to 2min (120s) + service level records are set to 75min (4500s) +*/ +#define MDNS_HOST_TTL 120 +#define MDNS_SERVICE_TTL 4500 + +/* + Compressed labels are flagged by the two topmost bits of the length byte being set +*/ +#define MDNS_DOMAIN_COMPRESS_MARK 0xC0 +/* + Avoid endless recursion because of malformed compressed labels +*/ +#define MDNS_DOMAIN_MAX_REDIRCTION 6 + +/* + Default service priority and weight in SRV answers +*/ +#define MDNS_SRV_PRIORITY 0 +#define MDNS_SRV_WEIGHT 0 + +/* + Delay between and number of probes for host and service domains + Delay between and number of announces for host and service domains + Delay between and number of service queries; the delay is multiplied by the resent number in + '_checkServiceQueryCache' +*/ +#define MDNS_PROBE_DELAY 250 +#define MDNS_PROBE_COUNT 3 +#define MDNS_ANNOUNCE_DELAY 1000 +#define MDNS_ANNOUNCE_COUNT 8 +#define MDNS_DYNAMIC_QUERY_RESEND_COUNT 5 +#define MDNS_DYNAMIC_QUERY_RESEND_DELAY 5000 + +/* + Force host domain to use only lowercase letters +*/ +//#define MDNS_FORCE_LOWERCASE_HOSTNAME + +/* + Enable/disable the usage of the F() macro in debug trace printf calls. + There needs to be an PGM compatible printf function to use this. + + USE_PGM_PRINTF and F +*/ +#define USE_PGM_PRINTF + +#ifdef USE_PGM_PRINTF +#else +#ifdef F +#undef F +#endif +#define F(A) A +#endif + +} // namespace MDNSImplementation + +} // namespace esp8266 + +// Include the main header, so the submodlues only need to include this header +#include "LEAmDNS.h" + +#endif // MDNS_PRIV_H diff --git a/libraries/LEAmDNS/src/LEAmDNS_Structs.cpp b/libraries/LEAmDNS/src/LEAmDNS_Structs.cpp new file mode 100644 index 00000000..3ab6e73c --- /dev/null +++ b/libraries/LEAmDNS/src/LEAmDNS_Structs.cpp @@ -0,0 +1,2031 @@ +/* + LEAmDNS_Structs.cpp + + License (MIT license): + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#include "ESP8266mDNS.h" +#include "LEAmDNS_Priv.h" +#include "LEAmDNS_lwIPdefs.h" + +namespace esp8266 { + +/* + LEAmDNS +*/ +namespace MDNSImplementation { + +/** + STRUCTS +*/ + +/** + MDNSResponder::stcMDNSServiceTxt + + One MDNS TXT item. + m_pcValue may be '\0'. + Objects can be chained together (list, m_pNext). + A 'm_bTemp' flag differentiates between static and dynamic items. + Output as byte array 'c#=1' is supported. +*/ + +/* + MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt constructor +*/ +MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt(const char* p_pcKey /*= 0*/, + const char* p_pcValue /*= 0*/, + bool p_bTemp /*= false*/) : + m_pNext(0), + m_pcKey(0), m_pcValue(0), m_bTemp(p_bTemp) { + setKey(p_pcKey); + setValue(p_pcValue); +} + +/* + MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt copy-constructor +*/ +MDNSResponder::stcMDNSServiceTxt::stcMDNSServiceTxt( + const MDNSResponder::stcMDNSServiceTxt& p_Other) : + m_pNext(0), + m_pcKey(0), m_pcValue(0), m_bTemp(false) { + operator=(p_Other); +} + +/* + MDNSResponder::stcMDNSServiceTxt::~stcMDNSServiceTxt destructor +*/ +MDNSResponder::stcMDNSServiceTxt::~stcMDNSServiceTxt(void) { + clear(); +} + +/* + MDNSResponder::stcMDNSServiceTxt::operator= +*/ +MDNSResponder::stcMDNSServiceTxt& +MDNSResponder::stcMDNSServiceTxt::operator=(const MDNSResponder::stcMDNSServiceTxt& p_Other) { + if (&p_Other != this) { + clear(); + set(p_Other.m_pcKey, p_Other.m_pcValue, p_Other.m_bTemp); + } + return *this; +} + +/* + MDNSResponder::stcMDNSServiceTxt::clear +*/ +bool MDNSResponder::stcMDNSServiceTxt::clear(void) { + releaseKey(); + releaseValue(); + return true; +} + +/* + MDNSResponder::stcMDNSServiceTxt::allocKey +*/ +char* MDNSResponder::stcMDNSServiceTxt::allocKey(size_t p_stLength) { + releaseKey(); + if (p_stLength) { + m_pcKey = new char[p_stLength + 1]; + } + return m_pcKey; +} + +/* + MDNSResponder::stcMDNSServiceTxt::setKey +*/ +bool MDNSResponder::stcMDNSServiceTxt::setKey(const char* p_pcKey, size_t p_stLength) { + bool bResult = false; + + releaseKey(); + if (p_stLength) { + if (allocKey(p_stLength)) { + strncpy(m_pcKey, p_pcKey, p_stLength); + m_pcKey[p_stLength] = 0; + bResult = true; + } + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceTxt::setKey +*/ +bool MDNSResponder::stcMDNSServiceTxt::setKey(const char* p_pcKey) { + return setKey(p_pcKey, (p_pcKey ? strlen(p_pcKey) : 0)); +} + +/* + MDNSResponder::stcMDNSServiceTxt::releaseKey +*/ +bool MDNSResponder::stcMDNSServiceTxt::releaseKey(void) { + if (m_pcKey) { + delete[] m_pcKey; + m_pcKey = 0; + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceTxt::allocValue +*/ +char* MDNSResponder::stcMDNSServiceTxt::allocValue(size_t p_stLength) { + releaseValue(); + if (p_stLength) { + m_pcValue = new char[p_stLength + 1]; + } + return m_pcValue; +} + +/* + MDNSResponder::stcMDNSServiceTxt::setValue +*/ +bool MDNSResponder::stcMDNSServiceTxt::setValue(const char* p_pcValue, size_t p_stLength) { + bool bResult = false; + + releaseValue(); + if (p_stLength) { + if (allocValue(p_stLength)) { + strncpy(m_pcValue, p_pcValue, p_stLength); + m_pcValue[p_stLength] = 0; + bResult = true; + } + } else { // No value -> also OK + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceTxt::setValue +*/ +bool MDNSResponder::stcMDNSServiceTxt::setValue(const char* p_pcValue) { + return setValue(p_pcValue, (p_pcValue ? strlen(p_pcValue) : 0)); +} + +/* + MDNSResponder::stcMDNSServiceTxt::releaseValue +*/ +bool MDNSResponder::stcMDNSServiceTxt::releaseValue(void) { + if (m_pcValue) { + delete[] m_pcValue; + m_pcValue = 0; + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceTxt::set +*/ +bool MDNSResponder::stcMDNSServiceTxt::set(const char* p_pcKey, const char* p_pcValue, + bool p_bTemp /*= false*/) { + m_bTemp = p_bTemp; + return ((setKey(p_pcKey)) && (setValue(p_pcValue))); +} + +/* + MDNSResponder::stcMDNSServiceTxt::update +*/ +bool MDNSResponder::stcMDNSServiceTxt::update(const char* p_pcValue) { + return setValue(p_pcValue); +} + +/* + MDNSResponder::stcMDNSServiceTxt::length + + length of eg. 'c#=1' without any closing '\0' +*/ +size_t MDNSResponder::stcMDNSServiceTxt::length(void) const { + size_t stLength = 0; + if (m_pcKey) { + stLength += strlen(m_pcKey); // Key + stLength += 1; // '=' + stLength += (m_pcValue ? strlen(m_pcValue) : 0); // Value + } + return stLength; +} + +/** + MDNSResponder::stcMDNSServiceTxts + + A list of zero or more MDNS TXT items. + Dynamic TXT items can be removed by 'removeTempTxts'. + A TXT item can be looke up by its 'key' member. + Export as ';'-separated byte array is supported. + Export as 'length byte coded' byte array is supported. + Comparison ((all A TXT items in B and equal) AND (all B TXT items in A and equal)) is + supported. + +*/ + +/* + MDNSResponder::stcMDNSServiceTxts::stcMDNSServiceTxts constructor +*/ +MDNSResponder::stcMDNSServiceTxts::stcMDNSServiceTxts(void) : m_pTxts(0) { } + +/* + MDNSResponder::stcMDNSServiceTxts::stcMDNSServiceTxts copy-constructor +*/ +MDNSResponder::stcMDNSServiceTxts::stcMDNSServiceTxts(const stcMDNSServiceTxts& p_Other) : + m_pTxts(0) { + operator=(p_Other); +} + +/* + MDNSResponder::stcMDNSServiceTxts::~stcMDNSServiceTxts destructor +*/ +MDNSResponder::stcMDNSServiceTxts::~stcMDNSServiceTxts(void) { + clear(); +} + +/* + MDNSResponder::stcMDNSServiceTxts::operator= +*/ +MDNSResponder::stcMDNSServiceTxts& +MDNSResponder::stcMDNSServiceTxts::operator=(const stcMDNSServiceTxts& p_Other) { + if (this != &p_Other) { + clear(); + + for (stcMDNSServiceTxt* pOtherTxt = p_Other.m_pTxts; pOtherTxt; + pOtherTxt = pOtherTxt->m_pNext) { + add(new stcMDNSServiceTxt(*pOtherTxt)); + } + } + return *this; +} + +/* + MDNSResponder::stcMDNSServiceTxts::clear +*/ +bool MDNSResponder::stcMDNSServiceTxts::clear(void) { + while (m_pTxts) { + stcMDNSServiceTxt* pNext = m_pTxts->m_pNext; + delete m_pTxts; + m_pTxts = pNext; + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceTxts::add +*/ +bool MDNSResponder::stcMDNSServiceTxts::add(MDNSResponder::stcMDNSServiceTxt* p_pTxt) { + bool bResult = false; + + if (p_pTxt) { + p_pTxt->m_pNext = m_pTxts; + m_pTxts = p_pTxt; + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::remove +*/ +bool MDNSResponder::stcMDNSServiceTxts::remove(stcMDNSServiceTxt* p_pTxt) { + bool bResult = false; + + if (p_pTxt) { + stcMDNSServiceTxt* pPred = m_pTxts; + while ((pPred) && (pPred->m_pNext != p_pTxt)) { + pPred = pPred->m_pNext; + } + if (pPred) { + pPred->m_pNext = p_pTxt->m_pNext; + delete p_pTxt; + bResult = true; + } else if (m_pTxts == p_pTxt) { // No predecessor, but first item + m_pTxts = p_pTxt->m_pNext; + delete p_pTxt; + bResult = true; + } + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::removeTempTxts +*/ +bool MDNSResponder::stcMDNSServiceTxts::removeTempTxts(void) { + bool bResult = true; + + stcMDNSServiceTxt* pTxt = m_pTxts; + while ((bResult) && (pTxt)) { + stcMDNSServiceTxt* pNext = pTxt->m_pNext; + if (pTxt->m_bTemp) { + bResult = remove(pTxt); + } + pTxt = pNext; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::find +*/ +MDNSResponder::stcMDNSServiceTxt* MDNSResponder::stcMDNSServiceTxts::find(const char* p_pcKey) { + stcMDNSServiceTxt* pResult = 0; + + for (stcMDNSServiceTxt* pTxt = m_pTxts; pTxt; pTxt = pTxt->m_pNext) { + if ((p_pcKey) && (0 == strcmp(pTxt->m_pcKey, p_pcKey))) { + pResult = pTxt; + break; + } + } + return pResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::find +*/ +const MDNSResponder::stcMDNSServiceTxt* +MDNSResponder::stcMDNSServiceTxts::find(const char* p_pcKey) const { + const stcMDNSServiceTxt* pResult = 0; + + for (const stcMDNSServiceTxt* pTxt = m_pTxts; pTxt; pTxt = pTxt->m_pNext) { + if ((p_pcKey) && (0 == strcmp(pTxt->m_pcKey, p_pcKey))) { + pResult = pTxt; + break; + } + } + return pResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::find +*/ +MDNSResponder::stcMDNSServiceTxt* +MDNSResponder::stcMDNSServiceTxts::find(const stcMDNSServiceTxt* p_pTxt) { + stcMDNSServiceTxt* pResult = 0; + + for (stcMDNSServiceTxt* pTxt = m_pTxts; pTxt; pTxt = pTxt->m_pNext) { + if (p_pTxt == pTxt) { + pResult = pTxt; + break; + } + } + return pResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::length +*/ +uint16_t MDNSResponder::stcMDNSServiceTxts::length(void) const { + uint16_t u16Length = 0; + + stcMDNSServiceTxt* pTxt = m_pTxts; + while (pTxt) { + u16Length += 1; // Length byte + u16Length += pTxt->length(); // Text + pTxt = pTxt->m_pNext; + } + return u16Length; +} + +/* + MDNSResponder::stcMDNSServiceTxts::c_strLength + + (incl. closing '\0'). Length bytes place is used for delimiting ';' and closing '\0' +*/ +size_t MDNSResponder::stcMDNSServiceTxts::c_strLength(void) const { + return length(); +} + +/* + MDNSResponder::stcMDNSServiceTxts::c_str +*/ +bool MDNSResponder::stcMDNSServiceTxts::c_str(char* p_pcBuffer) { + bool bResult = false; + + if (p_pcBuffer) { + bResult = true; + + *p_pcBuffer = 0; + for (stcMDNSServiceTxt* pTxt = m_pTxts; ((bResult) && (pTxt)); pTxt = pTxt->m_pNext) { + size_t stLength; + if ((bResult = (0 != (stLength = (pTxt->m_pcKey ? strlen(pTxt->m_pcKey) : 0))))) { + if (pTxt != m_pTxts) { + *p_pcBuffer++ = ';'; + } + strncpy(p_pcBuffer, pTxt->m_pcKey, stLength); + p_pcBuffer[stLength] = 0; + p_pcBuffer += stLength; + *p_pcBuffer++ = '='; + if ((stLength = (pTxt->m_pcValue ? strlen(pTxt->m_pcValue) : 0))) { + strncpy(p_pcBuffer, pTxt->m_pcValue, stLength); + p_pcBuffer[stLength] = 0; + p_pcBuffer += stLength; + } + } + } + *p_pcBuffer++ = 0; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::bufferLength + + (incl. closing '\0'). +*/ +size_t MDNSResponder::stcMDNSServiceTxts::bufferLength(void) const { + return (length() + 1); +} + +/* + MDNSResponder::stcMDNSServiceTxts::toBuffer +*/ +bool MDNSResponder::stcMDNSServiceTxts::buffer(char* p_pcBuffer) { + bool bResult = false; + + if (p_pcBuffer) { + bResult = true; + + *p_pcBuffer = 0; + for (stcMDNSServiceTxt* pTxt = m_pTxts; ((bResult) && (pTxt)); pTxt = pTxt->m_pNext) { + *(unsigned char*)p_pcBuffer++ = pTxt->length(); + size_t stLength; + if ((bResult = (0 != (stLength = (pTxt->m_pcKey ? strlen(pTxt->m_pcKey) : 0))))) { + memcpy(p_pcBuffer, pTxt->m_pcKey, stLength); + p_pcBuffer += stLength; + *p_pcBuffer++ = '='; + if ((stLength = (pTxt->m_pcValue ? strlen(pTxt->m_pcValue) : 0))) { + memcpy(p_pcBuffer, pTxt->m_pcValue, stLength); + p_pcBuffer += stLength; + } + } + } + *p_pcBuffer++ = 0; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::compare +*/ +bool MDNSResponder::stcMDNSServiceTxts::compare( + const MDNSResponder::stcMDNSServiceTxts& p_Other) const { + bool bResult = false; + + if ((bResult = (length() == p_Other.length()))) { + // Compare A->B + for (const stcMDNSServiceTxt* pTxt = m_pTxts; ((bResult) && (pTxt)); + pTxt = pTxt->m_pNext) { + const stcMDNSServiceTxt* pOtherTxt = p_Other.find(pTxt->m_pcKey); + bResult = ((pOtherTxt) && (pTxt->m_pcValue) && (pOtherTxt->m_pcValue) + && (strlen(pTxt->m_pcValue) == strlen(pOtherTxt->m_pcValue)) + && (0 == strcmp(pTxt->m_pcValue, pOtherTxt->m_pcValue))); + } + // Compare B->A + for (const stcMDNSServiceTxt* pOtherTxt = p_Other.m_pTxts; ((bResult) && (pOtherTxt)); + pOtherTxt = pOtherTxt->m_pNext) { + const stcMDNSServiceTxt* pTxt = find(pOtherTxt->m_pcKey); + bResult = ((pTxt) && (pOtherTxt->m_pcValue) && (pTxt->m_pcValue) + && (strlen(pOtherTxt->m_pcValue) == strlen(pTxt->m_pcValue)) + && (0 == strcmp(pOtherTxt->m_pcValue, pTxt->m_pcValue))); + } + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceTxts::operator== +*/ +bool MDNSResponder::stcMDNSServiceTxts::operator==(const stcMDNSServiceTxts& p_Other) const { + return compare(p_Other); +} + +/* + MDNSResponder::stcMDNSServiceTxts::operator!= +*/ +bool MDNSResponder::stcMDNSServiceTxts::operator!=(const stcMDNSServiceTxts& p_Other) const { + return !compare(p_Other); +} + +/** + MDNSResponder::stcMDNS_MsgHeader + + A MDNS message header. + +*/ + +/* + MDNSResponder::stcMDNS_MsgHeader::stcMDNS_MsgHeader +*/ +MDNSResponder::stcMDNS_MsgHeader::stcMDNS_MsgHeader( + uint16_t p_u16ID /*= 0*/, bool p_bQR /*= false*/, unsigned char p_ucOpcode /*= 0*/, + bool p_bAA /*= false*/, bool p_bTC /*= false*/, bool p_bRD /*= false*/, + bool p_bRA /*= false*/, unsigned char p_ucRCode /*= 0*/, uint16_t p_u16QDCount /*= 0*/, + uint16_t p_u16ANCount /*= 0*/, uint16_t p_u16NSCount /*= 0*/, + uint16_t p_u16ARCount /*= 0*/) : + m_u16ID(p_u16ID), + m_1bQR(p_bQR), m_4bOpcode(p_ucOpcode), m_1bAA(p_bAA), m_1bTC(p_bTC), m_1bRD(p_bRD), + m_1bRA(p_bRA), m_3bZ(0), m_4bRCode(p_ucRCode), m_u16QDCount(p_u16QDCount), + m_u16ANCount(p_u16ANCount), m_u16NSCount(p_u16NSCount), m_u16ARCount(p_u16ARCount) { +} + +/** + MDNSResponder::stcMDNS_RRDomain + + A MDNS domain object. + The labels of the domain are stored (DNS-like encoded) in 'm_acName': + [length byte]varlength label[length byte]varlength label[0] + 'm_u16NameLength' stores the used length of 'm_acName'. + Dynamic label addition is supported. + Comparison is supported. + Export as byte array 'esp8266.local' is supported. + +*/ + +/* + MDNSResponder::stcMDNS_RRDomain::stcMDNS_RRDomain constructor +*/ +MDNSResponder::stcMDNS_RRDomain::stcMDNS_RRDomain(void) : m_u16NameLength(0) { + clear(); +} + +/* + MDNSResponder::stcMDNS_RRDomain::stcMDNS_RRDomain copy-constructor +*/ +MDNSResponder::stcMDNS_RRDomain::stcMDNS_RRDomain(const stcMDNS_RRDomain& p_Other) : + m_u16NameLength(0) { + operator=(p_Other); +} + +/* + MDNSResponder::stcMDNS_RRDomain::operator = +*/ +MDNSResponder::stcMDNS_RRDomain& +MDNSResponder::stcMDNS_RRDomain::operator=(const stcMDNS_RRDomain& p_Other) { + if (&p_Other != this) { + memcpy(m_acName, p_Other.m_acName, sizeof(m_acName)); + m_u16NameLength = p_Other.m_u16NameLength; + } + return *this; +} + +/* + MDNSResponder::stcMDNS_RRDomain::clear +*/ +bool MDNSResponder::stcMDNS_RRDomain::clear(void) { + memset(m_acName, 0, sizeof(m_acName)); + m_u16NameLength = 0; + return true; +} + +/* + MDNSResponder::stcMDNS_RRDomain::addLabel +*/ +bool MDNSResponder::stcMDNS_RRDomain::addLabel(const char* p_pcLabel, + bool p_bPrependUnderline /*= false*/) { + bool bResult = false; + + size_t stLength = (p_pcLabel ? (strlen(p_pcLabel) + (p_bPrependUnderline ? 1 : 0)) : 0); + if ((MDNS_DOMAIN_LABEL_MAXLENGTH >= stLength) + && (MDNS_DOMAIN_MAXLENGTH >= (m_u16NameLength + (1 + stLength)))) { + // Length byte + m_acName[m_u16NameLength] = (unsigned char)stLength; // Might be 0! + ++m_u16NameLength; + // Label + if (stLength) { + if (p_bPrependUnderline) { + m_acName[m_u16NameLength++] = '_'; + --stLength; + } + strncpy(&(m_acName[m_u16NameLength]), p_pcLabel, stLength); + m_acName[m_u16NameLength + stLength] = 0; + m_u16NameLength += stLength; + } + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNS_RRDomain::compare +*/ +bool MDNSResponder::stcMDNS_RRDomain::compare(const stcMDNS_RRDomain& p_Other) const { + bool bResult = false; + + if (m_u16NameLength == p_Other.m_u16NameLength) { + const char* pT = m_acName; + const char* pO = p_Other.m_acName; + while ((pT) && (pO) && (*((unsigned char*)pT) == *((unsigned char*)pO)) + && // Same length AND + (0 == strncasecmp((pT + 1), (pO + 1), *((unsigned char*)pT)))) { // Same content + if (*((unsigned char*)pT)) { // Not 0 + pT += (1 + * ((unsigned char*)pT)); // Shift by length byte and length + pO += (1 + * ((unsigned char*)pO)); + } else { // Is 0 -> Successfully reached the end + bResult = true; + break; + } + } + } + return bResult; +} + +/* + MDNSResponder::stcMDNS_RRDomain::operator == +*/ +bool MDNSResponder::stcMDNS_RRDomain::operator==(const stcMDNS_RRDomain& p_Other) const { + return compare(p_Other); +} + +/* + MDNSResponder::stcMDNS_RRDomain::operator != +*/ +bool MDNSResponder::stcMDNS_RRDomain::operator!=(const stcMDNS_RRDomain& p_Other) const { + return !compare(p_Other); +} + +/* + MDNSResponder::stcMDNS_RRDomain::operator > +*/ +bool MDNSResponder::stcMDNS_RRDomain::operator>(const stcMDNS_RRDomain& p_Other) const { + // TODO: Check, if this is a good idea... + return !compare(p_Other); +} + +/* + MDNSResponder::stcMDNS_RRDomain::c_strLength +*/ +size_t MDNSResponder::stcMDNS_RRDomain::c_strLength(void) const { + size_t stLength = 0; + + unsigned char* pucLabelLength = (unsigned char*)m_acName; + while (*pucLabelLength) { + stLength += (*pucLabelLength + 1 /* +1 for '.' or '\0'*/); + pucLabelLength += (*pucLabelLength + 1); + } + return stLength; +} + +/* + MDNSResponder::stcMDNS_RRDomain::c_str +*/ +bool MDNSResponder::stcMDNS_RRDomain::c_str(char* p_pcBuffer) { + bool bResult = false; + + if (p_pcBuffer) { + *p_pcBuffer = 0; + unsigned char* pucLabelLength = (unsigned char*)m_acName; + while (*pucLabelLength) { + memcpy(p_pcBuffer, (const char*)(pucLabelLength + 1), *pucLabelLength); + p_pcBuffer += *pucLabelLength; + pucLabelLength += (*pucLabelLength + 1); + *p_pcBuffer++ = (*pucLabelLength ? '.' : '\0'); + } + bResult = true; + } + return bResult; +} + +/** + MDNSResponder::stcMDNS_RRAttributes + + A MDNS attributes object. + +*/ + +/* + MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes constructor +*/ +MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes( + uint16_t p_u16Type /*= 0*/, uint16_t p_u16Class /*= 1 DNS_RRCLASS_IN Internet*/) : + m_u16Type(p_u16Type), + m_u16Class(p_u16Class) { +} + +/* + MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes copy-constructor +*/ +MDNSResponder::stcMDNS_RRAttributes::stcMDNS_RRAttributes( + const MDNSResponder::stcMDNS_RRAttributes& p_Other) { + operator=(p_Other); +} + +/* + MDNSResponder::stcMDNS_RRAttributes::operator = +*/ +MDNSResponder::stcMDNS_RRAttributes& MDNSResponder::stcMDNS_RRAttributes::operator=( + const MDNSResponder::stcMDNS_RRAttributes& p_Other) { + if (&p_Other != this) { + m_u16Type = p_Other.m_u16Type; + m_u16Class = p_Other.m_u16Class; + } + return *this; +} + +/** + MDNSResponder::stcMDNS_RRHeader + + A MDNS record header (domain and attributes) object. + +*/ + +/* + MDNSResponder::stcMDNS_RRHeader::stcMDNS_RRHeader constructor +*/ +MDNSResponder::stcMDNS_RRHeader::stcMDNS_RRHeader(void) { } + +/* + MDNSResponder::stcMDNS_RRHeader::stcMDNS_RRHeader copy-constructor +*/ +MDNSResponder::stcMDNS_RRHeader::stcMDNS_RRHeader(const stcMDNS_RRHeader& p_Other) { + operator=(p_Other); +} + +/* + MDNSResponder::stcMDNS_RRHeader::operator = +*/ +MDNSResponder::stcMDNS_RRHeader& +MDNSResponder::stcMDNS_RRHeader::operator=(const MDNSResponder::stcMDNS_RRHeader& p_Other) { + if (&p_Other != this) { + m_Domain = p_Other.m_Domain; + m_Attributes = p_Other.m_Attributes; + } + return *this; +} + +/* + MDNSResponder::stcMDNS_RRHeader::clear +*/ +bool MDNSResponder::stcMDNS_RRHeader::clear(void) { + m_Domain.clear(); + return true; +} + +/** + MDNSResponder::stcMDNS_RRQuestion + + A MDNS question record object (header + question flags) + +*/ + +/* + MDNSResponder::stcMDNS_RRQuestion::stcMDNS_RRQuestion constructor +*/ +MDNSResponder::stcMDNS_RRQuestion::stcMDNS_RRQuestion(void) : m_pNext(0), m_bUnicast(false) { } + +/** + MDNSResponder::stcMDNS_RRAnswer + + A MDNS answer record object (header + answer content). + This is a 'virtual' base class for all other MDNS answer classes. + +*/ + +/* + MDNSResponder::stcMDNS_RRAnswer::stcMDNS_RRAnswer constructor +*/ +MDNSResponder::stcMDNS_RRAnswer::stcMDNS_RRAnswer( + enuAnswerType p_AnswerType, const MDNSResponder::stcMDNS_RRHeader& p_Header, + uint32_t p_u32TTL) : + m_pNext(0), + m_AnswerType(p_AnswerType), m_Header(p_Header), m_u32TTL(p_u32TTL) { + // Extract 'cache flush'-bit + m_bCacheFlush = (m_Header.m_Attributes.m_u16Class & 0x8000); + m_Header.m_Attributes.m_u16Class &= (~0x8000); +} + +/* + MDNSResponder::stcMDNS_RRAnswer::~stcMDNS_RRAnswer destructor +*/ +MDNSResponder::stcMDNS_RRAnswer::~stcMDNS_RRAnswer(void) { } + +/* + MDNSResponder::stcMDNS_RRAnswer::answerType +*/ +MDNSResponder::enuAnswerType MDNSResponder::stcMDNS_RRAnswer::answerType(void) const { + return m_AnswerType; +} + +/* + MDNSResponder::stcMDNS_RRAnswer::clear +*/ +bool MDNSResponder::stcMDNS_RRAnswer::clear(void) { + m_pNext = 0; + m_Header.clear(); + return true; +} + +/** + MDNSResponder::stcMDNS_RRAnswerA + + A MDNS A answer object. + Extends the base class by an IP4 address member. + +*/ + +#ifdef MDNS_IP4_SUPPORT +/* + MDNSResponder::stcMDNS_RRAnswerA::stcMDNS_RRAnswerA constructor +*/ +MDNSResponder::stcMDNS_RRAnswerA::stcMDNS_RRAnswerA( + const MDNSResponder::stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : + stcMDNS_RRAnswer(AnswerType_A, p_Header, p_u32TTL), + m_IPAddress(0, 0, 0, 0) { +} + +/* + MDNSResponder::stcMDNS_RRAnswerA::stcMDNS_RRAnswerA destructor +*/ +MDNSResponder::stcMDNS_RRAnswerA::~stcMDNS_RRAnswerA(void) { + clear(); +} + +/* + MDNSResponder::stcMDNS_RRAnswerA::clear +*/ +bool MDNSResponder::stcMDNS_RRAnswerA::clear(void) { + m_IPAddress = IPAddress(0, 0, 0, 0); + return true; +} +#endif + +/** + MDNSResponder::stcMDNS_RRAnswerPTR + + A MDNS PTR answer object. + Extends the base class by a MDNS domain member. + +*/ + +/* + MDNSResponder::stcMDNS_RRAnswerPTR::stcMDNS_RRAnswerPTR constructor +*/ +MDNSResponder::stcMDNS_RRAnswerPTR::stcMDNS_RRAnswerPTR( + const MDNSResponder::stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : + stcMDNS_RRAnswer(AnswerType_PTR, p_Header, p_u32TTL) { +} + +/* + MDNSResponder::stcMDNS_RRAnswerPTR::~stcMDNS_RRAnswerPTR destructor +*/ +MDNSResponder::stcMDNS_RRAnswerPTR::~stcMDNS_RRAnswerPTR(void) { + clear(); +} + +/* + MDNSResponder::stcMDNS_RRAnswerPTR::clear +*/ +bool MDNSResponder::stcMDNS_RRAnswerPTR::clear(void) { + m_PTRDomain.clear(); + return true; +} + +/** + MDNSResponder::stcMDNS_RRAnswerTXT + + A MDNS TXT answer object. + Extends the base class by a MDNS TXT items list member. + +*/ + +/* + MDNSResponder::stcMDNS_RRAnswerTXT::stcMDNS_RRAnswerTXT constructor +*/ +MDNSResponder::stcMDNS_RRAnswerTXT::stcMDNS_RRAnswerTXT( + const MDNSResponder::stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : + stcMDNS_RRAnswer(AnswerType_TXT, p_Header, p_u32TTL) { +} + +/* + MDNSResponder::stcMDNS_RRAnswerTXT::~stcMDNS_RRAnswerTXT destructor +*/ +MDNSResponder::stcMDNS_RRAnswerTXT::~stcMDNS_RRAnswerTXT(void) { + clear(); +} + +/* + MDNSResponder::stcMDNS_RRAnswerTXT::clear +*/ +bool MDNSResponder::stcMDNS_RRAnswerTXT::clear(void) { + m_Txts.clear(); + return true; +} + +/** + MDNSResponder::stcMDNS_RRAnswerAAAA + + A MDNS AAAA answer object. + (Should) extend the base class by an IP6 address member. + +*/ + +#ifdef MDNS_IP6_SUPPORT +/* + MDNSResponder::stcMDNS_RRAnswerAAAA::stcMDNS_RRAnswerAAAA constructor +*/ +MDNSResponder::stcMDNS_RRAnswerAAAA::stcMDNS_RRAnswerAAAA( + const MDNSResponder::stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : + stcMDNS_RRAnswer(AnswerType_AAAA, p_Header, p_u32TTL) { +} + +/* + MDNSResponder::stcMDNS_RRAnswerAAAA::~stcMDNS_RRAnswerAAAA destructor +*/ +MDNSResponder::stcMDNS_RRAnswerAAAA::~stcMDNS_RRAnswerAAAA(void) { + clear(); +} + +/* + MDNSResponder::stcMDNS_RRAnswerAAAA::clear +*/ +bool MDNSResponder::stcMDNS_RRAnswerAAAA::clear(void) { + return true; +} +#endif + +/** + MDNSResponder::stcMDNS_RRAnswerSRV + + A MDNS SRV answer object. + Extends the base class by a port member. + +*/ + +/* + MDNSResponder::stcMDNS_RRAnswerSRV::stcMDNS_RRAnswerSRV constructor +*/ +MDNSResponder::stcMDNS_RRAnswerSRV::stcMDNS_RRAnswerSRV( + const MDNSResponder::stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : + stcMDNS_RRAnswer(AnswerType_SRV, p_Header, p_u32TTL), + m_u16Priority(0), m_u16Weight(0), m_u16Port(0) { +} + +/* + MDNSResponder::stcMDNS_RRAnswerSRV::~stcMDNS_RRAnswerSRV destructor +*/ +MDNSResponder::stcMDNS_RRAnswerSRV::~stcMDNS_RRAnswerSRV(void) { + clear(); +} + +/* + MDNSResponder::stcMDNS_RRAnswerSRV::clear +*/ +bool MDNSResponder::stcMDNS_RRAnswerSRV::clear(void) { + m_u16Priority = 0; + m_u16Weight = 0; + m_u16Port = 0; + m_SRVDomain.clear(); + return true; +} + +/** + MDNSResponder::stcMDNS_RRAnswerGeneric + + An unknown (generic) MDNS answer object. + Extends the base class by a RDATA buffer member. + +*/ + +/* + MDNSResponder::stcMDNS_RRAnswerGeneric::stcMDNS_RRAnswerGeneric constructor +*/ +MDNSResponder::stcMDNS_RRAnswerGeneric::stcMDNS_RRAnswerGeneric( + const stcMDNS_RRHeader& p_Header, uint32_t p_u32TTL) : + stcMDNS_RRAnswer(AnswerType_Generic, p_Header, p_u32TTL), + m_u16RDLength(0), m_pu8RDData(0) { +} + +/* + MDNSResponder::stcMDNS_RRAnswerGeneric::~stcMDNS_RRAnswerGeneric destructor +*/ +MDNSResponder::stcMDNS_RRAnswerGeneric::~stcMDNS_RRAnswerGeneric(void) { + clear(); +} + +/* + MDNSResponder::stcMDNS_RRAnswerGeneric::clear +*/ +bool MDNSResponder::stcMDNS_RRAnswerGeneric::clear(void) { + if (m_pu8RDData) { + delete[] m_pu8RDData; + m_pu8RDData = 0; + } + m_u16RDLength = 0; + + return true; +} + +/** + MDNSResponder::stcProbeInformation + + Probing status information for a host or service domain + +*/ + +/* + MDNSResponder::stcProbeInformation::stcProbeInformation constructor +*/ +MDNSResponder::stcProbeInformation::stcProbeInformation(void) : + m_ProbingStatus(ProbingStatus_WaitingForData), m_u8SentCount(0), + m_Timeout(esp8266::polledTimeout::oneShotMs::neverExpires), m_bConflict(false), + m_bTiebreakNeeded(false), m_fnHostProbeResultCallback(0), m_fnServiceProbeResultCallback(0) { +} + +/* + MDNSResponder::stcProbeInformation::clear +*/ +bool MDNSResponder::stcProbeInformation::clear(bool p_bClearUserdata /*= false*/) { + m_ProbingStatus = ProbingStatus_WaitingForData; + m_u8SentCount = 0; + m_Timeout.resetToNeverExpires(); + m_bConflict = false; + m_bTiebreakNeeded = false; + if (p_bClearUserdata) { + m_fnHostProbeResultCallback = 0; + m_fnServiceProbeResultCallback = 0; + } + return true; +} + +/** + MDNSResponder::stcMDNSService + + A MDNS service object (to be announced by the MDNS responder) + The service instance may be '\0'; in this case the hostname is used + and the flag m_bAutoName is set. If the hostname changes, all 'auto- + named' services are renamed also. + m_u8Replymask is used while preparing a response to a MDNS query. It is + reset in '_sendMDNSMessage' afterwards. +*/ + +/* + MDNSResponder::stcMDNSService::stcMDNSService constructor +*/ +MDNSResponder::stcMDNSService::stcMDNSService(const char* p_pcName /*= 0*/, + const char* p_pcService /*= 0*/, + const char* p_pcProtocol /*= 0*/) : + m_pNext(0), + m_pcName(0), m_bAutoName(false), m_pcService(0), m_pcProtocol(0), m_u16Port(0), + m_u8ReplyMask(0), m_fnTxtCallback(0) { + setName(p_pcName); + setService(p_pcService); + setProtocol(p_pcProtocol); +} + +/* + MDNSResponder::stcMDNSService::~stcMDNSService destructor +*/ +MDNSResponder::stcMDNSService::~stcMDNSService(void) { + releaseName(); + releaseService(); + releaseProtocol(); +} + +/* + MDNSResponder::stcMDNSService::setName +*/ +bool MDNSResponder::stcMDNSService::setName(const char* p_pcName) { + bool bResult = false; + + releaseName(); + size_t stLength = (p_pcName ? strlen(p_pcName) : 0); + if (stLength) { + if ((bResult = (0 != (m_pcName = new char[stLength + 1])))) { + strncpy(m_pcName, p_pcName, stLength); + m_pcName[stLength] = 0; + } + } else { + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSService::releaseName +*/ +bool MDNSResponder::stcMDNSService::releaseName(void) { + if (m_pcName) { + delete[] m_pcName; + m_pcName = 0; + } + return true; +} + +/* + MDNSResponder::stcMDNSService::setService +*/ +bool MDNSResponder::stcMDNSService::setService(const char* p_pcService) { + bool bResult = false; + + releaseService(); + size_t stLength = (p_pcService ? strlen(p_pcService) : 0); + if (stLength) { + if ((bResult = (0 != (m_pcService = new char[stLength + 1])))) { + strncpy(m_pcService, p_pcService, stLength); + m_pcService[stLength] = 0; + } + } else { + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSService::releaseService +*/ +bool MDNSResponder::stcMDNSService::releaseService(void) { + if (m_pcService) { + delete[] m_pcService; + m_pcService = 0; + } + return true; +} + +/* + MDNSResponder::stcMDNSService::setProtocol +*/ +bool MDNSResponder::stcMDNSService::setProtocol(const char* p_pcProtocol) { + bool bResult = false; + + releaseProtocol(); + size_t stLength = (p_pcProtocol ? strlen(p_pcProtocol) : 0); + if (stLength) { + if ((bResult = (0 != (m_pcProtocol = new char[stLength + 1])))) { + strncpy(m_pcProtocol, p_pcProtocol, stLength); + m_pcProtocol[stLength] = 0; + } + } else { + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSService::releaseProtocol +*/ +bool MDNSResponder::stcMDNSService::releaseProtocol(void) { + if (m_pcProtocol) { + delete[] m_pcProtocol; + m_pcProtocol = 0; + } + return true; +} + +/** + MDNSResponder::stcMDNSServiceQuery + + A MDNS service query object. + Service queries may be static or dynamic. + As the static service query is processed in the blocking function 'queryService', + only one static service service may exist. The processing of the answers is done + on the WiFi-stack side of the ESP stack structure (via 'UDPContext.onRx(_update)'). + +*/ + +/** + MDNSResponder::stcMDNSServiceQuery::stcAnswer + + One answer for a service query. + Every answer must contain + - a service instance entry (pivot), + and may contain + - a host domain, + - a port + - an IP4 address + (- an IP6 address) + - a MDNS TXTs + The existence of a component is flagged in 'm_u32ContentFlags'. + For every answer component a TTL value is maintained. + Answer objects can be connected to a linked list. + + For the host domain, service domain and TXTs components, a char array + representation can be retrieved (which is created on demand). + +*/ + +/** + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL + + The TTL (Time-To-Live) for an specific answer content. + The 80% and outdated states are calculated based on the current time (millis) + and the 'set' time (also millis). + If the answer is scheduled for an update, the corresponding flag should be set. + + / + + / * + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::stcTTL constructor + / + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::stcTTL(uint32_t p_u32TTL / *= 0* /) + : m_bUpdateScheduled(false) { + + set(p_u32TTL * 1000); + } + + / * + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::set + / + bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::set(uint32_t p_u32TTL) { + + m_TTLTimeFlag.restart(p_u32TTL * 1000); + m_bUpdateScheduled = false; + + return true; + } + + / * + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::has80Percent + / + bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::has80Percent(void) const { + + return ((m_TTLTimeFlag.getTimeout()) && + (!m_bUpdateScheduled) && + (m_TTLTimeFlag.hypotheticalTimeout((m_TTLTimeFlag.getTimeout() * 800) / 1000))); + } + + / * + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::isOutdated + / + bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::isOutdated(void) const { + + return ((m_TTLTimeFlag.getTimeout()) && + (m_TTLTimeFlag.flagged())); + }*/ + +/** + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL + + The TTL (Time-To-Live) for an specific answer content. + The 80% and outdated states are calculated based on the current time (millis) + and the 'set' time (also millis). + If the answer is scheduled for an update, the corresponding flag should be set. + +*/ + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::stcTTL constructor +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::stcTTL(void) : + m_u32TTL(0), m_TTLTimeout(esp8266::polledTimeout::oneShotMs::neverExpires), + m_timeoutLevel(TIMEOUTLEVEL_UNSET) { +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::set +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::set(uint32_t p_u32TTL) { + m_u32TTL = p_u32TTL; + if (m_u32TTL) { + m_timeoutLevel = TIMEOUTLEVEL_BASE; // Set to 80% + m_TTLTimeout.reset(timeout()); + } else { + m_timeoutLevel = TIMEOUTLEVEL_UNSET; // undef + m_TTLTimeout.resetToNeverExpires(); + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::flagged +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::flagged(void) { + return ((m_u32TTL) && (TIMEOUTLEVEL_UNSET != m_timeoutLevel) && (m_TTLTimeout.expired())); +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::restart +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::restart(void) { + bool bResult = true; + + if ((TIMEOUTLEVEL_BASE <= m_timeoutLevel) && // >= 80% AND + (TIMEOUTLEVEL_FINAL > m_timeoutLevel)) { // < 100% + m_timeoutLevel += TIMEOUTLEVEL_INTERVAL; // increment by 5% + m_TTLTimeout.reset(timeout()); + } else { + bResult = false; + m_TTLTimeout.resetToNeverExpires(); + m_timeoutLevel = TIMEOUTLEVEL_UNSET; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::prepareDeletion +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::prepareDeletion(void) { + m_timeoutLevel = TIMEOUTLEVEL_FINAL; + m_TTLTimeout.reset(1 * 1000); // See RFC 6762, 10.1 + + return true; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::finalTimeoutLevel +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::finalTimeoutLevel(void) const { + return (TIMEOUTLEVEL_FINAL == m_timeoutLevel); +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::timeout +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::timeoutBase::timeType +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::timeout(void) const { + if (TIMEOUTLEVEL_BASE == m_timeoutLevel) { // 80% + return (m_u32TTL * 800L); // to milliseconds + } else if ((TIMEOUTLEVEL_BASE < m_timeoutLevel) && // >80% AND + (TIMEOUTLEVEL_FINAL >= m_timeoutLevel)) { // <= 100% + return (m_u32TTL * 50L); + } // else: invalid + return MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcTTL::timeoutBase::neverExpires; +} + +#ifdef MDNS_IP4_SUPPORT +/** + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address + +*/ + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address::stcIP4Address constructor +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address::stcIP4Address( + IPAddress p_IPAddress, uint32_t p_u32TTL /*= 0*/) : + m_pNext(0), + m_IPAddress(p_IPAddress) { + m_TTL.set(p_u32TTL); +} +#endif + +/** + MDNSResponder::stcMDNSServiceQuery::stcAnswer +*/ + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcAnswer constructor +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcAnswer(void) : + m_pNext(0), m_pcServiceDomain(0), m_pcHostDomain(0), m_u16Port(0), m_pcTxts(0), +#ifdef MDNS_IP4_SUPPORT + m_pIP4Addresses(0), +#endif +#ifdef MDNS_IP6_SUPPORT + m_pIP6Addresses(0), +#endif + m_u32ContentFlags(0) { +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::~stcAnswer destructor +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::~stcAnswer(void) { + clear(); +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::clear +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::clear(void) { + return ((releaseTxts()) && +#ifdef MDNS_IP4_SUPPORT + (releaseIP4Addresses()) && +#endif +#ifdef MDNS_IP6_SUPPORT + (releaseIP6Addresses()) +#endif + (releaseHostDomain()) + && (releaseServiceDomain())); +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocServiceDomain + + Alloc memory for the char array representation of the service domain. + +*/ +char* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocServiceDomain(size_t p_stLength) { + releaseServiceDomain(); + if (p_stLength) { + m_pcServiceDomain = new char[p_stLength]; + } + return m_pcServiceDomain; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseServiceDomain +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseServiceDomain(void) { + if (m_pcServiceDomain) { + delete[] m_pcServiceDomain; + m_pcServiceDomain = 0; + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocHostDomain + + Alloc memory for the char array representation of the host domain. + +*/ +char* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocHostDomain(size_t p_stLength) { + releaseHostDomain(); + if (p_stLength) { + m_pcHostDomain = new char[p_stLength]; + } + return m_pcHostDomain; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseHostDomain +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseHostDomain(void) { + if (m_pcHostDomain) { + delete[] m_pcHostDomain; + m_pcHostDomain = 0; + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocTxts + + Alloc memory for the char array representation of the TXT items. + +*/ +char* MDNSResponder::stcMDNSServiceQuery::stcAnswer::allocTxts(size_t p_stLength) { + releaseTxts(); + if (p_stLength) { + m_pcTxts = new char[p_stLength]; + } + return m_pcTxts; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseTxts +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseTxts(void) { + if (m_pcTxts) { + delete[] m_pcTxts; + m_pcTxts = 0; + } + return true; +} + +#ifdef MDNS_IP4_SUPPORT +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseIP4Addresses +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseIP4Addresses(void) { + while (m_pIP4Addresses) { + stcIP4Address* pNext = m_pIP4Addresses->m_pNext; + delete m_pIP4Addresses; + m_pIP4Addresses = pNext; + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::addIP4Address +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::addIP4Address( + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* p_pIP4Address) { + bool bResult = false; + + if (p_pIP4Address) { + p_pIP4Address->m_pNext = m_pIP4Addresses; + m_pIP4Addresses = p_pIP4Address; + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::removeIP4Address +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::removeIP4Address( + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* p_pIP4Address) { + bool bResult = false; + + if (p_pIP4Address) { + stcIP4Address* pPred = m_pIP4Addresses; + while ((pPred) && (pPred->m_pNext != p_pIP4Address)) { + pPred = pPred->m_pNext; + } + if (pPred) { + pPred->m_pNext = p_pIP4Address->m_pNext; + delete p_pIP4Address; + bResult = true; + } else if (m_pIP4Addresses == p_pIP4Address) { // No predecessor, but first item + m_pIP4Addresses = p_pIP4Address->m_pNext; + delete p_pIP4Address; + bResult = true; + } + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP4Address (const) +*/ +const MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* +MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP4Address( + const IPAddress& p_IPAddress) const { + return (stcIP4Address*)(((const stcAnswer*)this)->findIP4Address(p_IPAddress)); +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP4Address +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* +MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP4Address(const IPAddress& p_IPAddress) { + stcIP4Address* pIP4Address = m_pIP4Addresses; + while (pIP4Address) { + if (pIP4Address->m_IPAddress == p_IPAddress) { + break; + } + pIP4Address = pIP4Address->m_pNext; + } + return pIP4Address; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressCount +*/ +uint32_t MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressCount(void) const { + uint32_t u32Count = 0; + + stcIP4Address* pIP4Address = m_pIP4Addresses; + while (pIP4Address) { + ++u32Count; + pIP4Address = pIP4Address->m_pNext; + } + return u32Count; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressAtIndex +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* +MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressAtIndex(uint32_t p_u32Index) { + return (stcIP4Address*)(((const stcAnswer*)this)->IP4AddressAtIndex(p_u32Index)); +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressAtIndex (const) +*/ +const MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP4Address* +MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP4AddressAtIndex(uint32_t p_u32Index) const { + const stcIP4Address* pIP4Address = 0; + + if (((uint32_t)(-1) != p_u32Index) && (m_pIP4Addresses)) { + uint32_t u32Index; + for (pIP4Address = m_pIP4Addresses, u32Index = 0; + ((pIP4Address) && (u32Index < p_u32Index)); + pIP4Address = pIP4Address->m_pNext, ++u32Index) + ; + } + return pIP4Address; +} +#endif + +#ifdef MDNS_IP6_SUPPORT +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseIP6Addresses +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::releaseIP6Addresses(void) { + while (m_pIP6Addresses) { + stcIP6Address* pNext = m_pIP6Addresses->m_pNext; + delete m_pIP6Addresses; + m_pIP6Addresses = pNext; + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::addIP6Address +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::addIP6Address( + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* p_pIP6Address) { + bool bResult = false; + + if (p_pIP6Address) { + p_pIP6Address->m_pNext = m_pIP6Addresses; + m_pIP6Addresses = p_pIP6Address; + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::removeIP6Address +*/ +bool MDNSResponder::stcMDNSServiceQuery::stcAnswer::removeIP6Address( + MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* p_pIP6Address) { + bool bResult = false; + + if (p_pIP6Address) { + stcIP6Address* pPred = m_pIP6Addresses; + while ((pPred) && (pPred->m_pNext != p_pIP6Address)) { + pPred = pPred->m_pNext; + } + if (pPred) { + pPred->m_pNext = p_pIP6Address->m_pNext; + delete p_pIP6Address; + bResult = true; + } else if (m_pIP6Addresses == p_pIP6Address) { // No predecessor, but first item + m_pIP6Addresses = p_pIP6Address->m_pNext; + delete p_pIP6Address; + bResult = true; + } + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP6Address +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* +MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP6Address(const IP6Address& p_IPAddress) { + return (stcIP6Address*)(((const stcAnswer*)this)->findIP6Address(p_IPAddress)); +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP6Address (const) +*/ +const MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* +MDNSResponder::stcMDNSServiceQuery::stcAnswer::findIP6Address( + const IPAddress& p_IPAddress) const { + const stcIP6Address* pIP6Address = m_pIP6Addresses; + while (pIP6Address) { + if (p_IP6Address->m_IPAddress == p_IPAddress) { + break; + } + pIP6Address = pIP6Address->m_pNext; + } + return pIP6Address; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressCount +*/ +uint32_t MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressCount(void) const { + uint32_t u32Count = 0; + + stcIP6Address* pIP6Address = m_pIP6Addresses; + while (pIP6Address) { + ++u32Count; + pIP6Address = pIP6Address->m_pNext; + } + return u32Count; +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressAtIndex (const) +*/ +const MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* +MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressAtIndex(uint32_t p_u32Index) const { + return (stcIP6Address*)(((const stcAnswer*)this)->IP6AddressAtIndex(p_u32Index)); +} + +/* + MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressAtIndex +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer::stcIP6Address* +MDNSResponder::stcMDNSServiceQuery::stcAnswer::IP6AddressAtIndex(uint32_t p_u32Index) { + stcIP6Address* pIP6Address = 0; + + if (((uint32_t)(-1) != p_u32Index) && (m_pIP6Addresses)) { + uint32_t u32Index; + for (pIP6Address = m_pIP6Addresses, u32Index = 0; + ((pIP6Address) && (u32Index < p_u32Index)); + pIP6Address = pIP6Address->m_pNext, ++u32Index) + ; + } + return pIP6Address; +} +#endif + +/** + MDNSResponder::stcMDNSServiceQuery + + A service query object. + A static query is flagged via 'm_bLegacyQuery'; while the function 'queryService' + is waiting for answers, the internal flag 'm_bAwaitingAnswers' is set. When the + timeout is reached, the flag is removed. These two flags are only used for static + service queries. + All answers to the service query are stored in 'm_pAnswers' list. + Individual answers may be addressed by index (in the list of answers). + Every time a answer component is added (or changes) in a dynamic service query, + the callback 'm_fnCallback' is called. + The answer list may be searched by service and host domain. + + Service query object may be connected to a linked list. +*/ + +/* + MDNSResponder::stcMDNSServiceQuery::stcMDNSServiceQuery constructor +*/ +MDNSResponder::stcMDNSServiceQuery::stcMDNSServiceQuery(void) : + m_pNext(0), m_fnCallback(0), m_bLegacyQuery(false), m_u8SentCount(0), + m_ResendTimeout(esp8266::polledTimeout::oneShotMs::neverExpires), m_bAwaitingAnswers(true), + m_pAnswers(0) { + clear(); +} + +/* + MDNSResponder::stcMDNSServiceQuery::~stcMDNSServiceQuery destructor +*/ +MDNSResponder::stcMDNSServiceQuery::~stcMDNSServiceQuery(void) { + clear(); +} + +/* + MDNSResponder::stcMDNSServiceQuery::clear +*/ +bool MDNSResponder::stcMDNSServiceQuery::clear(void) { + m_fnCallback = 0; + m_bLegacyQuery = false; + m_u8SentCount = 0; + m_ResendTimeout.resetToNeverExpires(); + m_bAwaitingAnswers = true; + while (m_pAnswers) { + stcAnswer* pNext = m_pAnswers->m_pNext; + delete m_pAnswers; + m_pAnswers = pNext; + } + return true; +} + +/* + MDNSResponder::stcMDNSServiceQuery::answerCount +*/ +uint32_t MDNSResponder::stcMDNSServiceQuery::answerCount(void) const { + uint32_t u32Count = 0; + + stcAnswer* pAnswer = m_pAnswers; + while (pAnswer) { + ++u32Count; + pAnswer = pAnswer->m_pNext; + } + return u32Count; +} + +/* + MDNSResponder::stcMDNSServiceQuery::answerAtIndex +*/ +const MDNSResponder::stcMDNSServiceQuery::stcAnswer* +MDNSResponder::stcMDNSServiceQuery::answerAtIndex(uint32_t p_u32Index) const { + const stcAnswer* pAnswer = 0; + + if (((uint32_t)(-1) != p_u32Index) && (m_pAnswers)) { + uint32_t u32Index; + for (pAnswer = m_pAnswers, u32Index = 0; ((pAnswer) && (u32Index < p_u32Index)); + pAnswer = pAnswer->m_pNext, ++u32Index) + ; + } + return pAnswer; +} + +/* + MDNSResponder::stcMDNSServiceQuery::answerAtIndex +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer* +MDNSResponder::stcMDNSServiceQuery::answerAtIndex(uint32_t p_u32Index) { + return (stcAnswer*)(((const stcMDNSServiceQuery*)this)->answerAtIndex(p_u32Index)); +} + +/* + MDNSResponder::stcMDNSServiceQuery::indexOfAnswer +*/ +uint32_t MDNSResponder::stcMDNSServiceQuery::indexOfAnswer( + const MDNSResponder::stcMDNSServiceQuery::stcAnswer* p_pAnswer) const { + uint32_t u32Index = 0; + + for (const stcAnswer* pAnswer = m_pAnswers; pAnswer; pAnswer = pAnswer->m_pNext, ++u32Index) { + if (pAnswer == p_pAnswer) { + return u32Index; + } + } + return ((uint32_t)(-1)); +} + +/* + MDNSResponder::stcMDNSServiceQuery::addAnswer +*/ +bool MDNSResponder::stcMDNSServiceQuery::addAnswer( + MDNSResponder::stcMDNSServiceQuery::stcAnswer* p_pAnswer) { + bool bResult = false; + + if (p_pAnswer) { + p_pAnswer->m_pNext = m_pAnswers; + m_pAnswers = p_pAnswer; + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceQuery::removeAnswer +*/ +bool MDNSResponder::stcMDNSServiceQuery::removeAnswer( + MDNSResponder::stcMDNSServiceQuery::stcAnswer* p_pAnswer) { + bool bResult = false; + + if (p_pAnswer) { + stcAnswer* pPred = m_pAnswers; + while ((pPred) && (pPred->m_pNext != p_pAnswer)) { + pPred = pPred->m_pNext; + } + if (pPred) { + pPred->m_pNext = p_pAnswer->m_pNext; + delete p_pAnswer; + bResult = true; + } else if (m_pAnswers == p_pAnswer) { // No predecessor, but first item + m_pAnswers = p_pAnswer->m_pNext; + delete p_pAnswer; + bResult = true; + } + } + return bResult; +} + +/* + MDNSResponder::stcMDNSServiceQuery::findAnswerForServiceDomain +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer* +MDNSResponder::stcMDNSServiceQuery::findAnswerForServiceDomain( + const MDNSResponder::stcMDNS_RRDomain& p_ServiceDomain) { + stcAnswer* pAnswer = m_pAnswers; + while (pAnswer) { + if (pAnswer->m_ServiceDomain == p_ServiceDomain) { + break; + } + pAnswer = pAnswer->m_pNext; + } + return pAnswer; +} + +/* + MDNSResponder::stcMDNSServiceQuery::findAnswerForHostDomain +*/ +MDNSResponder::stcMDNSServiceQuery::stcAnswer* +MDNSResponder::stcMDNSServiceQuery::findAnswerForHostDomain( + const MDNSResponder::stcMDNS_RRDomain& p_HostDomain) { + stcAnswer* pAnswer = m_pAnswers; + while (pAnswer) { + if (pAnswer->m_HostDomain == p_HostDomain) { + break; + } + pAnswer = pAnswer->m_pNext; + } + return pAnswer; +} + +/** + MDNSResponder::stcMDNSSendParameter + + A 'collection' of properties and flags for one MDNS query or response. + Mainly managed by the 'Control' functions. + The current offset in the UPD output buffer is tracked to be able to do + a simple host or service domain compression. + +*/ + +/** + MDNSResponder::stcMDNSSendParameter::stcDomainCacheItem + + A cached host or service domain, incl. the offset in the UDP output buffer. + +*/ + +/* + MDNSResponder::stcMDNSSendParameter::stcDomainCacheItem::stcDomainCacheItem constructor +*/ +MDNSResponder::stcMDNSSendParameter::stcDomainCacheItem::stcDomainCacheItem( + const void* p_pHostnameOrService, bool p_bAdditionalData, uint32_t p_u16Offset) : + m_pNext(0), + m_pHostnameOrService(p_pHostnameOrService), m_bAdditionalData(p_bAdditionalData), + m_u16Offset(p_u16Offset) { +} + +/** + MDNSResponder::stcMDNSSendParameter +*/ + +/* + MDNSResponder::stcMDNSSendParameter::stcMDNSSendParameter constructor +*/ +MDNSResponder::stcMDNSSendParameter::stcMDNSSendParameter(void) : + m_pQuestions(0), m_pDomainCacheItems(0) { + clear(); +} + +/* + MDNSResponder::stcMDNSSendParameter::~stcMDNSSendParameter destructor +*/ +MDNSResponder::stcMDNSSendParameter::~stcMDNSSendParameter(void) { + clear(); +} + +/* + MDNSResponder::stcMDNSSendParameter::clear +*/ +bool MDNSResponder::stcMDNSSendParameter::clear(void) { + m_u16ID = 0; + m_u8HostReplyMask = 0; + m_u16Offset = 0; + + m_bLegacyQuery = false; + m_bResponse = false; + m_bAuthorative = false; + m_bUnicast = false; + m_bUnannounce = false; + + m_bCacheFlush = true; + + while (m_pQuestions) { + stcMDNS_RRQuestion* pNext = m_pQuestions->m_pNext; + delete m_pQuestions; + m_pQuestions = pNext; + } + + return clearCachedNames(); + ; +} +/* + MDNSResponder::stcMDNSSendParameter::clear cached names +*/ +bool MDNSResponder::stcMDNSSendParameter::clearCachedNames(void) { + m_u16Offset = 0; + + while (m_pDomainCacheItems) { + stcDomainCacheItem* pNext = m_pDomainCacheItems->m_pNext; + delete m_pDomainCacheItems; + m_pDomainCacheItems = pNext; + } + m_pDomainCacheItems = nullptr; + + return true; +} + +/* + MDNSResponder::stcMDNSSendParameter::shiftOffset +*/ +bool MDNSResponder::stcMDNSSendParameter::shiftOffset(uint16_t p_u16Shift) { + m_u16Offset += p_u16Shift; + return true; +} + +/* + MDNSResponder::stcMDNSSendParameter::addDomainCacheItem +*/ +bool MDNSResponder::stcMDNSSendParameter::addDomainCacheItem(const void* p_pHostnameOrService, + bool p_bAdditionalData, + uint16_t p_u16Offset) { + bool bResult = false; + + stcDomainCacheItem* pNewItem = 0; + if ((p_pHostnameOrService) && (p_u16Offset) + && ((pNewItem + = new stcDomainCacheItem(p_pHostnameOrService, p_bAdditionalData, p_u16Offset)))) { + pNewItem->m_pNext = m_pDomainCacheItems; + bResult = ((m_pDomainCacheItems = pNewItem)); + } + return bResult; +} + +/* + MDNSResponder::stcMDNSSendParameter::findCachedDomainOffset +*/ +uint16_t +MDNSResponder::stcMDNSSendParameter::findCachedDomainOffset(const void* p_pHostnameOrService, + bool p_bAdditionalData) const { + const stcDomainCacheItem* pCacheItem = m_pDomainCacheItems; + + for (; pCacheItem; pCacheItem = pCacheItem->m_pNext) { + if ((pCacheItem->m_pHostnameOrService == p_pHostnameOrService) + && (pCacheItem->m_bAdditionalData == p_bAdditionalData)) { // Found cache item + break; + } + } + return (pCacheItem ? pCacheItem->m_u16Offset : 0); +} + +} // namespace MDNSImplementation + +} // namespace esp8266 diff --git a/libraries/LEAmDNS/src/LEAmDNS_Transfer.cpp b/libraries/LEAmDNS/src/LEAmDNS_Transfer.cpp new file mode 100644 index 00000000..91651db0 --- /dev/null +++ b/libraries/LEAmDNS/src/LEAmDNS_Transfer.cpp @@ -0,0 +1,1747 @@ +/* + LEAmDNS_Transfer.cpp + + License (MIT license): + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +extern "C" +{ + //#include "user_interface.h" +} + +#include "ESP8266mDNS.h" +#include "LEAmDNS_lwIPdefs.h" +#include "LEAmDNS_Priv.h" + +namespace esp8266 { + +/* + LEAmDNS +*/ +namespace MDNSImplementation { + +/** + CONST STRINGS +*/ +static const char* scpcLocal = "local"; +static const char* scpcServices = "services"; +static const char* scpcDNSSD = "dns-sd"; +static const char* scpcUDP = "udp"; +// static const char* scpcTCP = "tcp"; + +#ifdef MDNS_IP4_SUPPORT +static const char* scpcReverseIP4Domain = "in-addr"; +#endif +#ifdef MDNS_IP6_SUPPORT +static const char* scpcReverseIP6Domain = "ip6"; +#endif +static const char* scpcReverseTopDomain = "arpa"; + +/** + TRANSFER +*/ + +/** + SENDING +*/ + +/* + MDNSResponder::_sendMDNSMessage + + Unicast responses are prepared and sent directly to the querier. + Multicast responses or queries are transferred to _sendMDNSMessage_Multicast + + Any reply flags in installed services are removed at the end! + +*/ +bool MDNSResponder::_sendMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + bool bResult = true; + + if (p_rSendParameter.m_bResponse + && p_rSendParameter.m_bUnicast) { // Unicast response -> Send to querier + DEBUG_EX_ERR(if (!m_pUDPContext->getRemoteAddress()) { + DEBUG_OUTPUT.printf_P(PSTR( + "[MDNSResponder] _sendMDNSMessage: MISSING remote address for response!\n")); + }); + IPAddress ipRemote; + ipRemote = m_pUDPContext->getRemoteAddress(); + bResult + = ((_prepareMDNSMessage(p_rSendParameter, m_pUDPContext->getInputNetif()->ip_addr)) + && (m_pUDPContext->sendTimeout(ipRemote, m_pUDPContext->getRemotePort(), + MDNS_UDPCONTEXT_TIMEOUT))); + } else { // Multicast response + bResult = _sendMDNSMessage_Multicast(p_rSendParameter); + } + + // Finally clear service reply masks + for (stcMDNSService* pService = m_pServices; pService; pService = pService->m_pNext) { + pService->m_u8ReplyMask = 0; + } + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _sendMDNSMessage: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_sendMDNSMessage_Multicast + + Fills the UDP output buffer (via _prepareMDNSMessage) and sends the buffer + via the selected WiFi interface (Station or AP) +*/ +bool +MDNSResponder::_sendMDNSMessage_Multicast(MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + bool bResult = false; + + for (netif* pNetIf = netif_list; pNetIf; pNetIf = pNetIf->next) { + if (netif_is_up(pNetIf)) { + IPAddress fromIPAddress; + // fromIPAddress = _getResponseMulticastInterface(); + fromIPAddress = pNetIf->ip_addr; + m_pUDPContext->setMulticastInterface(fromIPAddress); + +#ifdef MDNS_IP4_SUPPORT + IPAddress toMulticastAddress(DNS_MQUERY_IPV4_GROUP_INIT); +#endif +#ifdef MDNS_IP6_SUPPORT + // TODO: set multicast address + IPAddress toMulticastAddress(DNS_MQUERY_IPV6_GROUP_INIT); +#endif + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: Will send to '%s'.\n"), + toMulticastAddress.toString().c_str());); + bResult = ((_prepareMDNSMessage(p_rSendParameter, fromIPAddress)) + && (m_pUDPContext->sendTimeout(toMulticastAddress, DNS_MQUERY_PORT, + MDNS_UDPCONTEXT_TIMEOUT))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _sendMDNSMessage_Multicast: FAILED!\n")); + }); + } + } + return bResult; +} + +/* + MDNSResponder::_prepareMDNSMessage + + The MDNS message is composed in a two-step process. + In the first loop 'only' the header information (mainly number of answers) are collected, + while in the seconds loop, the header and all queries and answers are written to the UDP + output buffer. + +*/ +bool MDNSResponder::_prepareMDNSMessage(MDNSResponder::stcMDNSSendParameter& p_rSendParameter, + IPAddress p_IPAddress) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _prepareMDNSMessage\n"));); + bool bResult = true; + p_rSendParameter.clearCachedNames(); // Need to remove cached names, p_SendParameter might + // have been used before on other interface + + // Prepare header; count answers + stcMDNS_MsgHeader msgHeader(p_rSendParameter.m_u16ID, p_rSendParameter.m_bResponse, 0, + p_rSendParameter.m_bAuthorative); + // If this is a response, the answers are anwers, + // else this is a query or probe and the answers go into auth section + uint16_t& ru16Answers + = (p_rSendParameter.m_bResponse ? msgHeader.m_u16ANCount : msgHeader.m_u16NSCount); + + /** + enuSequence + */ + enum enuSequence { + Sequence_Count = 0, + Sequence_Send = 1 + }; + + // Two step sequence: 'Count' and 'Send' + for (uint32_t sequence = Sequence_Count; ((bResult) && (sequence <= Sequence_Send)); + ++sequence) { + DEBUG_EX_INFO(if (Sequence_Send == sequence) { + DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: ID:%u QR:%u OP:%u AA:%u TC:%u RD:%u " + "RA:%u R:%u QD:%u AN:%u NS:%u AR:%u\n"), + (unsigned)msgHeader.m_u16ID, (unsigned)msgHeader.m_1bQR, + (unsigned)msgHeader.m_4bOpcode, (unsigned)msgHeader.m_1bAA, + (unsigned)msgHeader.m_1bTC, (unsigned)msgHeader.m_1bRD, + (unsigned)msgHeader.m_1bRA, (unsigned)msgHeader.m_4bRCode, + (unsigned)msgHeader.m_u16QDCount, (unsigned)msgHeader.m_u16ANCount, + (unsigned)msgHeader.m_u16NSCount, (unsigned)msgHeader.m_u16ARCount); + }); + // Count/send + // Header + bResult + = ((Sequence_Count == sequence) ? true + : _writeMDNSMsgHeader(msgHeader, p_rSendParameter)); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSMsgHeader FAILED!\n"));); + // Questions + for (stcMDNS_RRQuestion* pQuestion = p_rSendParameter.m_pQuestions; + ((bResult) && (pQuestion)); pQuestion = pQuestion->m_pNext) { + ((Sequence_Count == sequence) + ? ++msgHeader.m_u16QDCount + : (bResult = _writeMDNSQuestion(*pQuestion, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSQuestion FAILED!\n"));); + } + + // Answers and authoritative answers +#ifdef MDNS_IP4_SUPPORT + if ((bResult) && (p_rSendParameter.m_u8HostReplyMask & ContentFlag_A)) { + ((Sequence_Count == sequence) + ? ++ru16Answers + : (bResult = _writeMDNSAnswer_A(p_IPAddress, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_A(A) FAILED!\n"));); + } + if ((bResult) && (p_rSendParameter.m_u8HostReplyMask & ContentFlag_PTR_IP4)) { + ((Sequence_Count == sequence) + ? ++ru16Answers + : (bResult = _writeMDNSAnswer_PTR_IP4(p_IPAddress, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P(PSTR( + "[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_PTR_IP4 FAILED!\n"));); + } +#endif +#ifdef MDNS_IP6_SUPPORT + if ((bResult) && (p_rSendParameter.m_u8HostReplyMask & ContentFlag_AAAA)) { + ((Sequence_Count == sequence) + ? ++ru16Answers + : (bResult = _writeMDNSAnswer_AAAA(p_IPAddress, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P(PSTR( + "[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_AAAA(A) FAILED!\n"));); + } + if ((bResult) && (p_rSendParameter.m_u8HostReplyMask & ContentFlag_PTR_IP6)) { + ((Sequence_Count == sequence) + ? ++ru16Answers + : (bResult = _writeMDNSAnswer_PTR_IP6(p_IPAddress, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P(PSTR( + "[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_PTR_IP6 FAILED!\n"));); + } +#endif + + for (stcMDNSService* pService = m_pServices; ((bResult) && (pService)); + pService = pService->m_pNext) { + if ((bResult) && (pService->m_u8ReplyMask & ContentFlag_PTR_TYPE)) { + ((Sequence_Count == sequence) + ? ++ru16Answers + : (bResult = _writeMDNSAnswer_PTR_TYPE(*pService, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_PTR_TYPE " + "FAILED!\n"));); + } + if ((bResult) && (pService->m_u8ReplyMask & ContentFlag_PTR_NAME)) { + ((Sequence_Count == sequence) + ? ++ru16Answers + : (bResult = _writeMDNSAnswer_PTR_NAME(*pService, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_PTR_NAME " + "FAILED!\n"));); + } + if ((bResult) && (pService->m_u8ReplyMask & ContentFlag_SRV)) { + ((Sequence_Count == sequence) + ? ++ru16Answers + : (bResult = _writeMDNSAnswer_SRV(*pService, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_SRV(A) " + "FAILED!\n"));); + } + if ((bResult) && (pService->m_u8ReplyMask & ContentFlag_TXT)) { + ((Sequence_Count == sequence) + ? ++ru16Answers + : (bResult = _writeMDNSAnswer_TXT(*pService, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_TXT(A) " + "FAILED!\n"));); + } + } // for services + + // Additional answers +#ifdef MDNS_IP4_SUPPORT + bool bNeedsAdditionalAnswerA = false; +#endif +#ifdef MDNS_IP6_SUPPORT + bool bNeedsAdditionalAnswerAAAA = false; +#endif + for (stcMDNSService* pService = m_pServices; ((bResult) && (pService)); + pService = pService->m_pNext) { + if ((bResult) && (pService->m_u8ReplyMask & ContentFlag_PTR_NAME) + && // If PTR_NAME is requested, AND + (!(pService->m_u8ReplyMask + & ContentFlag_SRV))) { // NOT SRV -> add SRV as additional answer + ((Sequence_Count == sequence) + ? ++msgHeader.m_u16ARCount + : (bResult = _writeMDNSAnswer_SRV(*pService, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_SRV(B) " + "FAILED!\n"));); + } + if ((bResult) && (pService->m_u8ReplyMask & ContentFlag_PTR_NAME) + && // If PTR_NAME is requested, AND + (!(pService->m_u8ReplyMask + & ContentFlag_TXT))) { // NOT TXT -> add TXT as additional answer + ((Sequence_Count == sequence) + ? ++msgHeader.m_u16ARCount + : (bResult = _writeMDNSAnswer_TXT(*pService, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_TXT(B) " + "FAILED!\n"));); + } + if ((pService->m_u8ReplyMask & (ContentFlag_PTR_NAME | ContentFlag_SRV)) + || // If service instance name or SRV OR + (p_rSendParameter.m_u8HostReplyMask + & (ContentFlag_A | ContentFlag_AAAA))) { // any host IP address is requested +#ifdef MDNS_IP4_SUPPORT + if ((bResult) + && (!(p_rSendParameter.m_u8HostReplyMask + & ContentFlag_A))) { // Add IP4 address + bNeedsAdditionalAnswerA = true; + } +#endif +#ifdef MDNS_IP6_SUPPORT + if ((bResult) + && (!(p_rSendParameter.m_u8HostReplyMask + & ContentFlag_AAAA))) { // Add IP6 address + bNeedsAdditionalAnswerAAAA = true; + } +#endif + } + } // for services + + // Answer A needed? +#ifdef MDNS_IP4_SUPPORT + if ((bResult) && (bNeedsAdditionalAnswerA)) { + ((Sequence_Count == sequence) + ? ++msgHeader.m_u16ARCount + : (bResult = _writeMDNSAnswer_A(p_IPAddress, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_A(B) FAILED!\n"));); + } +#endif +#ifdef MDNS_IP6_SUPPORT + // Answer AAAA needed? + if ((bResult) && (bNeedsAdditionalAnswerAAAA)) { + ((Sequence_Count == sequence) + ? ++msgHeader.m_u16ARCount + : (bResult = _writeMDNSAnswer_AAAA(p_IPAddress, p_rSendParameter))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P(PSTR( + "[MDNSResponder] _prepareMDNSMessage: _writeMDNSAnswer_AAAA(B) FAILED!\n"));); + } +#endif + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: Loop %i FAILED!\n"), sequence);); + } // for sequence + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _prepareMDNSMessage: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_sendMDNSServiceQuery + + Creates and sends a PTR query for the given service domain. + +*/ +bool +MDNSResponder::_sendMDNSServiceQuery(const MDNSResponder::stcMDNSServiceQuery& p_ServiceQuery) { + return _sendMDNSQuery(p_ServiceQuery.m_ServiceTypeDomain, DNS_RRTYPE_PTR); +} + +/* + MDNSResponder::_sendMDNSQuery + + Creates and sends a query for the given domain and query type. + +*/ +bool MDNSResponder::_sendMDNSQuery(const MDNSResponder::stcMDNS_RRDomain& p_QueryDomain, + uint16_t p_u16QueryType, + stcMDNSServiceQuery::stcAnswer* p_pKnownAnswers /*= 0*/) { + bool bResult = false; + + stcMDNSSendParameter sendParameter; + if (0 != ((sendParameter.m_pQuestions = new stcMDNS_RRQuestion))) { + sendParameter.m_pQuestions->m_Header.m_Domain = p_QueryDomain; + + sendParameter.m_pQuestions->m_Header.m_Attributes.m_u16Type = p_u16QueryType; + // It seems, that some mDNS implementations don't support 'unicast response' + // questions... + sendParameter.m_pQuestions->m_Header.m_Attributes.m_u16Class + = (/*0x8000 |*/ DNS_RRCLASS_IN); // /*Unicast &*/ INternet + + // TODO: Add known answer to the query + (void)p_pKnownAnswers; + + bResult = _sendMDNSMessage(sendParameter); + } // else: FAILED to alloc question + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _sendMDNSQuery: FAILED to alloc question!\n"));); + return bResult; +} + +/** + HELPERS +*/ + +/** + RESOURCE RECORDS +*/ + +/* + MDNSResponder::_readRRQuestion + + Reads a question (eg. MyESP._http._tcp.local ANY IN) from the UPD input buffer. + +*/ +bool MDNSResponder::_readRRQuestion(MDNSResponder::stcMDNS_RRQuestion& p_rRRQuestion) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRQuestion\n"));); + + bool bResult = false; + + if ((bResult = _readRRHeader(p_rRRQuestion.m_Header))) { + // Extract unicast flag from class field + p_rRRQuestion.m_bUnicast = (p_rRRQuestion.m_Header.m_Attributes.m_u16Class & 0x8000); + p_rRRQuestion.m_Header.m_Attributes.m_u16Class &= (~0x8000); + + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRQuestion ")); + _printRRDomain(p_rRRQuestion.m_Header.m_Domain); DEBUG_OUTPUT.printf_P( + PSTR(" Type:0x%04X Class:0x%04X %s\n"), + (unsigned)p_rRRQuestion.m_Header.m_Attributes.m_u16Type, + (unsigned)p_rRRQuestion.m_Header.m_Attributes.m_u16Class, + (p_rRRQuestion.m_bUnicast ? "Unicast" : "Multicast"));); + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRQuestion: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_readRRAnswer + + Reads an answer (eg. _http._tcp.local PTR OP TTL MyESP._http._tcp.local) + from the UDP input buffer. + After reading the domain and type info, the further processing of the answer + is transferred the answer specific reading functions. + Unknown answer types are processed by the generic answer reader (to remove them + from the input buffer). + +*/ +bool MDNSResponder::_readRRAnswer(MDNSResponder::stcMDNS_RRAnswer*& p_rpRRAnswer) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswer\n"));); + + bool bResult = false; + + stcMDNS_RRHeader header; + uint32_t u32TTL; + uint16_t u16RDLength; + if ((_readRRHeader(header)) && (_udpRead32(u32TTL)) && (_udpRead16(u16RDLength))) { + /* DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswer: Reading 0x%04X answer + (class:0x%04X, TTL:%u, RDLength:%u) for "), header.m_Attributes.m_u16Type, + header.m_Attributes.m_u16Class, u32TTL, u16RDLength); + _printRRDomain(header.m_Domain); + DEBUG_OUTPUT.printf_P(PSTR("\n")); + );*/ + + switch (header.m_Attributes.m_u16Type + & (~0x8000)) { // Topmost bit might carry 'cache flush' flag +#ifdef MDNS_IP4_SUPPORT + case DNS_RRTYPE_A: + p_rpRRAnswer = new stcMDNS_RRAnswerA(header, u32TTL); + bResult = _readRRAnswerA(*(stcMDNS_RRAnswerA*&)p_rpRRAnswer, u16RDLength); + break; +#endif + case DNS_RRTYPE_PTR: + p_rpRRAnswer = new stcMDNS_RRAnswerPTR(header, u32TTL); + bResult = _readRRAnswerPTR(*(stcMDNS_RRAnswerPTR*&)p_rpRRAnswer, u16RDLength); + break; + case DNS_RRTYPE_TXT: + p_rpRRAnswer = new stcMDNS_RRAnswerTXT(header, u32TTL); + bResult = _readRRAnswerTXT(*(stcMDNS_RRAnswerTXT*&)p_rpRRAnswer, u16RDLength); + break; +#ifdef MDNS_IP6_SUPPORT + case DNS_RRTYPE_AAAA: + p_rpRRAnswer = new stcMDNS_RRAnswerAAAA(header, u32TTL); + bResult = _readRRAnswerAAAA(*(stcMDNS_RRAnswerAAAA*&)p_rpRRAnswer, u16RDLength); + break; +#endif + case DNS_RRTYPE_SRV: + p_rpRRAnswer = new stcMDNS_RRAnswerSRV(header, u32TTL); + bResult = _readRRAnswerSRV(*(stcMDNS_RRAnswerSRV*&)p_rpRRAnswer, u16RDLength); + break; + default: + p_rpRRAnswer = new stcMDNS_RRAnswerGeneric(header, u32TTL); + bResult + = _readRRAnswerGeneric(*(stcMDNS_RRAnswerGeneric*&)p_rpRRAnswer, u16RDLength); + break; + } + DEBUG_EX_INFO( + if ((bResult) && (p_rpRRAnswer)) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswer: ")); + _printRRDomain(p_rpRRAnswer->m_Header.m_Domain); + DEBUG_OUTPUT.printf_P(PSTR(" Type:0x%04X Class:0x%04X TTL:%u, RDLength:%u "), + p_rpRRAnswer->m_Header.m_Attributes.m_u16Type, + p_rpRRAnswer->m_Header.m_Attributes.m_u16Class, + p_rpRRAnswer->m_u32TTL, u16RDLength); + switch (header.m_Attributes.m_u16Type + & (~0x8000)) { // Topmost bit might carry 'cache flush' flag +#ifdef MDNS_IP4_SUPPORT + case DNS_RRTYPE_A: + DEBUG_OUTPUT.printf_P( + PSTR("A IP:%s"), + ((stcMDNS_RRAnswerA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str()); + break; +#endif + case DNS_RRTYPE_PTR: + DEBUG_OUTPUT.printf_P(PSTR("PTR ")); + _printRRDomain(((stcMDNS_RRAnswerPTR*&)p_rpRRAnswer)->m_PTRDomain); + break; + case DNS_RRTYPE_TXT: { + size_t stTxtLength + = ((stcMDNS_RRAnswerTXT*&)p_rpRRAnswer)->m_Txts.c_strLength(); + char* pTxts = new char[stTxtLength]; + if (pTxts) { + ((stcMDNS_RRAnswerTXT*&)p_rpRRAnswer)->m_Txts.c_str(pTxts); + DEBUG_OUTPUT.printf_P(PSTR("TXT(%zu) %s"), stTxtLength, pTxts); + delete[] pTxts; + } + break; + } +#ifdef MDNS_IP6_SUPPORT + case DNS_RRTYPE_AAAA: + DEBUG_OUTPUT.printf_P( + PSTR("AAAA IP:%s"), + ((stcMDNS_RRAnswerA*&)p_rpRRAnswer)->m_IPAddress.toString().c_str()); + break; +#endif + case DNS_RRTYPE_SRV: + DEBUG_OUTPUT.printf_P(PSTR("SRV Port:%u "), + ((stcMDNS_RRAnswerSRV*&)p_rpRRAnswer)->m_u16Port); + _printRRDomain(((stcMDNS_RRAnswerSRV*&)p_rpRRAnswer)->m_SRVDomain); + break; + default: + DEBUG_OUTPUT.printf_P(PSTR("generic ")); + break; + } + DEBUG_OUTPUT.printf_P(PSTR("\n")); + } else { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswer: FAILED to read " + "specific answer of type 0x%04X!\n"), + p_rpRRAnswer->m_Header.m_Attributes.m_u16Type); + }); // DEBUG_EX_INFO + } + DEBUG_EX_ERR(if (!bResult) + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswer: FAILED!\n"));); + return bResult; +} + +#ifdef MDNS_IP4_SUPPORT +/* + MDNSResponder::_readRRAnswerA +*/ +bool MDNSResponder::_readRRAnswerA(MDNSResponder::stcMDNS_RRAnswerA& p_rRRAnswerA, + uint16_t p_u16RDLength) { + uint32_t u32IP4Address; + bool bResult = ((MDNS_IP4_SIZE == p_u16RDLength) + && (_udpReadBuffer((unsigned char*)&u32IP4Address, MDNS_IP4_SIZE)) + && ((p_rRRAnswerA.m_IPAddress = IPAddress(u32IP4Address)))); + DEBUG_EX_ERR(if (!bResult) + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswerA: FAILED!\n"));); + return bResult; +} +#endif + +/* + MDNSResponder::_readRRAnswerPTR +*/ +bool MDNSResponder::_readRRAnswerPTR(MDNSResponder::stcMDNS_RRAnswerPTR& p_rRRAnswerPTR, + uint16_t p_u16RDLength) { + bool bResult = ((p_u16RDLength) && (_readRRDomain(p_rRRAnswerPTR.m_PTRDomain))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRAnswerPTR: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_readRRAnswerTXT + + Read TXT items from a buffer like 4c#=15ff=20 +*/ +bool MDNSResponder::_readRRAnswerTXT(MDNSResponder::stcMDNS_RRAnswerTXT& p_rRRAnswerTXT, + uint16_t p_u16RDLength) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswerTXT: RDLength:%u\n"), + p_u16RDLength);); + bool bResult = true; + + p_rRRAnswerTXT.clear(); + if (p_u16RDLength) { + bResult = false; + + unsigned char* pucBuffer = new unsigned char[p_u16RDLength]; + if (pucBuffer) { + if (_udpReadBuffer(pucBuffer, p_u16RDLength)) { + bResult = true; + + const unsigned char* pucCursor = pucBuffer; + while ((pucCursor < (pucBuffer + p_u16RDLength)) && (bResult)) { + bResult = false; + + stcMDNSServiceTxt* pTxt = 0; + unsigned char ucLength = *pucCursor++; // Length of the next txt item + if (ucLength) { + DEBUG_EX_INFO( + static char sacBuffer[64]; *sacBuffer = 0; + uint8_t u8MaxLength + = ((ucLength > (sizeof(sacBuffer) - 1)) ? (sizeof(sacBuffer) - 1) + : ucLength); + strncpy(sacBuffer, (const char*)pucCursor, u8MaxLength); + sacBuffer[u8MaxLength] = 0; DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRAnswerTXT: Item(%u): %s\n"), + ucLength, sacBuffer);); + + unsigned char* pucEqualSign = (unsigned char*)strchr( + (const char*)pucCursor, '='); // Position of the '=' sign + unsigned char ucKeyLength; + if ((pucEqualSign) && ((ucKeyLength = (pucEqualSign - pucCursor)))) { + unsigned char ucValueLength + = (ucLength - (pucEqualSign - pucCursor + 1)); + bResult = (((pTxt = new stcMDNSServiceTxt)) + && (pTxt->setKey((const char*)pucCursor, ucKeyLength)) + && (pTxt->setValue((const char*)(pucEqualSign + 1), + ucValueLength))); + } else { + DEBUG_EX_ERR( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswerTXT: " + "INVALID TXT format (No '=')!\n"));); + } + pucCursor += ucLength; + } else { // no/zero length TXT + DEBUG_EX_INFO( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswerTXT: TXT " + "answer contains no items.\n"));); + bResult = true; + } + + if ((bResult) && (pTxt)) { // Everything is fine so far + // Link TXT item to answer TXTs + pTxt->m_pNext = p_rRRAnswerTXT.m_Txts.m_pTxts; + p_rRRAnswerTXT.m_Txts.m_pTxts = pTxt; + } else { // At least no TXT (might be OK, if length was 0) OR an error + if (!bResult) { + DEBUG_EX_ERR( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswerTXT: " + "FAILED to read TXT item!\n")); + DEBUG_OUTPUT.printf_P(PSTR("RData dump:\n")); _udpDump( + (m_pUDPContext->tell() - p_u16RDLength), p_u16RDLength); + DEBUG_OUTPUT.printf_P(PSTR("\n"));); + } + if (pTxt) { + delete pTxt; + pTxt = 0; + } + p_rRRAnswerTXT.clear(); + } + } // while + + DEBUG_EX_ERR(if (!bResult) { // Some failure + DEBUG_OUTPUT.printf_P(PSTR("RData dump:\n")); + _udpDump((m_pUDPContext->tell() - p_u16RDLength), + p_u16RDLength); + DEBUG_OUTPUT.printf_P(PSTR("\n")); + }); + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRAnswerTXT: FAILED to read TXT content!\n"));); + } + // Clean up + delete[] pucBuffer; + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAnswerTXT: FAILED " + "to alloc buffer for TXT content!\n"));); + } + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRAnswerTXT: WARNING! No content!\n"));); + } + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRAnswerTXT: FAILED!\n"));); + return bResult; +} + +#ifdef MDNS_IP6_SUPPORT +bool MDNSResponder::_readRRAnswerAAAA(MDNSResponder::stcMDNS_RRAnswerAAAA& p_rRRAnswerAAAA, + uint16_t p_u16RDLength) { + bool bResult = false; + // TODO: Implement + return bResult; +} +#endif + +/* + MDNSResponder::_readRRAnswerSRV +*/ +bool MDNSResponder::_readRRAnswerSRV(MDNSResponder::stcMDNS_RRAnswerSRV& p_rRRAnswerSRV, + uint16_t p_u16RDLength) { + bool bResult + = (((3 * sizeof(uint16_t)) < p_u16RDLength) + && (_udpRead16(p_rRRAnswerSRV.m_u16Priority)) + && (_udpRead16(p_rRRAnswerSRV.m_u16Weight)) && (_udpRead16(p_rRRAnswerSRV.m_u16Port)) + && (_readRRDomain(p_rRRAnswerSRV.m_SRVDomain))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRAnswerSRV: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_readRRAnswerGeneric +*/ +bool +MDNSResponder::_readRRAnswerGeneric(MDNSResponder::stcMDNS_RRAnswerGeneric& p_rRRAnswerGeneric, + uint16_t p_u16RDLength) { + bool bResult = (0 == p_u16RDLength); + + p_rRRAnswerGeneric.clear(); + if (((p_rRRAnswerGeneric.m_u16RDLength = p_u16RDLength)) + && ((p_rRRAnswerGeneric.m_pu8RDData + = new unsigned char[p_rRRAnswerGeneric.m_u16RDLength]))) { + bResult + = _udpReadBuffer(p_rRRAnswerGeneric.m_pu8RDData, p_rRRAnswerGeneric.m_u16RDLength); + } + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRAnswerGeneric: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_readRRHeader +*/ +bool MDNSResponder::_readRRHeader(MDNSResponder::stcMDNS_RRHeader& p_rRRHeader) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRHeader\n"));); + + bool bResult = ((_readRRDomain(p_rRRHeader.m_Domain)) + && (_readRRAttributes(p_rRRHeader.m_Attributes))); + DEBUG_EX_ERR(if (!bResult) + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRHeader: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_readRRDomain + + Reads a (maybe multilevel compressed) domain from the UDP input buffer. + +*/ +bool MDNSResponder::_readRRDomain(MDNSResponder::stcMDNS_RRDomain& p_rRRDomain) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRDomain\n"));); + + bool bResult = ((p_rRRDomain.clear()) && (_readRRDomain_Loop(p_rRRDomain, 0))); + DEBUG_EX_ERR(if (!bResult) + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRDomain: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_readRRDomain_Loop + + Reads a domain from the UDP input buffer. For every compression level, the functions + calls itself recursively. To avoid endless recursion because of malformed MDNS records, + the maximum recursion depth is set by MDNS_DOMAIN_MAX_REDIRCTION. + +*/ +bool MDNSResponder::_readRRDomain_Loop(MDNSResponder::stcMDNS_RRDomain& p_rRRDomain, + uint8_t p_u8Depth) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRDomain_Loop(%u)\n"), + // p_u8Depth);); + + bool bResult = false; + + if (MDNS_DOMAIN_MAX_REDIRCTION >= p_u8Depth) { + bResult = true; + + uint8_t u8Len = 0; + do { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRDomain_Loop(%u): + // Offset:%u p0:%02x\n"), p_u8Depth, m_pUDPContext->tell(), + // m_pUDPContext->peek());); + _udpRead8(u8Len); + + if (u8Len & MDNS_DOMAIN_COMPRESS_MARK) { + // Compressed label(s) + uint16_t u16Offset = ((u8Len & ~MDNS_DOMAIN_COMPRESS_MARK) + << 8); // Implicit BE to LE conversion! + _udpRead8(u8Len); + u16Offset |= u8Len; + + if (m_pUDPContext->isValidOffset(u16Offset)) { + size_t stCurrentPosition + = m_pUDPContext->tell(); // Prepare return from recursion + + // DEBUG_EX_RX(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] + // _readRRDomain_Loop(%u): Redirecting from %u to %u!\n"), p_u8Depth, + // stCurrentPosition, u16Offset);); + m_pUDPContext->seek(u16Offset); + if (_readRRDomain_Loop(p_rRRDomain, p_u8Depth + 1)) { // Do recursion + // DEBUG_EX_RX(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] + // _readRRDomain_Loop(%u): Succeeded to read redirected label! Returning + // to %u\n"), p_u8Depth, stCurrentPosition);); + m_pUDPContext->seek(stCurrentPosition); // Restore after recursion + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRDomain_Loop(%u): FAILED to read " + "redirected label!\n"), + p_u8Depth);); + bResult = false; + } + } else { + DEBUG_EX_ERR( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRDomain_Loop(%u): " + "INVALID offset in redirection!\n"), + p_u8Depth);); + bResult = false; + } + break; + } else { + // Normal (uncompressed) label (maybe '\0' only) + if (MDNS_DOMAIN_MAXLENGTH > (p_rRRDomain.m_u16NameLength + u8Len)) { + // Add length byte + p_rRRDomain.m_acName[p_rRRDomain.m_u16NameLength] = u8Len; + ++(p_rRRDomain.m_u16NameLength); + if (u8Len) { // Add name + if ((bResult = _udpReadBuffer( + (unsigned char*) & ( + p_rRRDomain.m_acName[p_rRRDomain.m_u16NameLength]), + u8Len))) { + /* DEBUG_EX_INFO( + p_rRRDomain.m_acName[p_rRRDomain.m_u16NameLength + u8Len] = + 0; // Closing '\0' for printing + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] + _readRRDomain_Loop(%u): Domain label (%u): %s\n"), p_u8Depth, + (unsigned)(p_rRRDomain.m_acName[p_rRRDomain.m_u16NameLength - + 1]), &(p_rRRDomain.m_acName[p_rRRDomain.m_u16NameLength])); + );*/ + + p_rRRDomain.m_u16NameLength += u8Len; + } + } + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] + // _readRRDomain_Loop(2) offset:%u p0:%x\n"), m_pUDPContext->tell(), + // m_pUDPContext->peek());); + } else { + DEBUG_EX_ERR( + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRDomain_Loop(%u): " + "ERROR! Domain name too long (%u + %u)!\n"), + p_u8Depth, p_rRRDomain.m_u16NameLength, u8Len);); + bResult = false; + break; + } + } + } while ((bResult) && (0 != u8Len)); + } else { + DEBUG_EX_ERR(DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRDomain_Loop(%u): ERROR! Too many redirections!\n"), + p_u8Depth);); + } + return bResult; +} + +/* + MDNSResponder::_readRRAttributes +*/ +bool MDNSResponder::_readRRAttributes(MDNSResponder::stcMDNS_RRAttributes& p_rRRAttributes) { + // DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readRRAttributes\n"));); + + bool bResult + = ((_udpRead16(p_rRRAttributes.m_u16Type)) && (_udpRead16(p_rRRAttributes.m_u16Class))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _readRRAttributes: FAILED!\n"));); + return bResult; +} + +/* + DOMAIN NAMES +*/ + +/* + MDNSResponder::_buildDomainForHost + + Builds a MDNS host domain (eg. esp8266.local) for the given hostname. + +*/ +bool MDNSResponder::_buildDomainForHost(const char* p_pcHostname, + MDNSResponder::stcMDNS_RRDomain& p_rHostDomain) const { + p_rHostDomain.clear(); + bool bResult = ((p_pcHostname) && (*p_pcHostname) && (p_rHostDomain.addLabel(p_pcHostname)) + && (p_rHostDomain.addLabel(scpcLocal)) && (p_rHostDomain.addLabel(0))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _buildDomainForHost: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_buildDomainForDNSSD + + Builds the '_services._dns-sd._udp.local' domain. + Used while detecting generic service enum question (DNS-SD) and answering these questions. + +*/ +bool MDNSResponder::_buildDomainForDNSSD(MDNSResponder::stcMDNS_RRDomain& p_rDNSSDDomain) const { + p_rDNSSDDomain.clear(); + bool bResult = ((p_rDNSSDDomain.addLabel(scpcServices, true)) + && (p_rDNSSDDomain.addLabel(scpcDNSSD, true)) + && (p_rDNSSDDomain.addLabel(scpcUDP, true)) + && (p_rDNSSDDomain.addLabel(scpcLocal)) && (p_rDNSSDDomain.addLabel(0))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _buildDomainForDNSSD: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_buildDomainForService + + Builds the domain for the given service (eg. _http._tcp.local or + MyESP._http._tcp.local (if p_bIncludeName is set)). + +*/ +bool +MDNSResponder::_buildDomainForService(const MDNSResponder::stcMDNSService& p_Service, + bool p_bIncludeName, + MDNSResponder::stcMDNS_RRDomain& p_rServiceDomain) const { + p_rServiceDomain.clear(); + bool bResult + = (((!p_bIncludeName) || (p_rServiceDomain.addLabel(p_Service.m_pcName))) + && (p_rServiceDomain.addLabel(p_Service.m_pcService, true)) + && (p_rServiceDomain.addLabel(p_Service.m_pcProtocol, true)) + && (p_rServiceDomain.addLabel(scpcLocal)) && (p_rServiceDomain.addLabel(0))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _buildDomainForService: FAILED!\n"));); + return bResult; +} + +/* + MDNSResponder::_buildDomainForService + + Builds the domain for the given service properties (eg. _http._tcp.local). + The usual prepended '_' are added, if missing in the input strings. + +*/ +bool +MDNSResponder::_buildDomainForService(const char* p_pcService, const char* p_pcProtocol, + MDNSResponder::stcMDNS_RRDomain& p_rServiceDomain) const { + p_rServiceDomain.clear(); + bool bResult + = ((p_pcService) && (p_pcProtocol) + && (p_rServiceDomain.addLabel(p_pcService, ('_' != *p_pcService))) + && (p_rServiceDomain.addLabel(p_pcProtocol, ('_' != *p_pcProtocol))) + && (p_rServiceDomain.addLabel(scpcLocal)) && (p_rServiceDomain.addLabel(0))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _buildDomainForService: FAILED for (%s.%s)!\n"), + (p_pcService ? : "-"), (p_pcProtocol ? : "-"));); + return bResult; +} + +#ifdef MDNS_IP4_SUPPORT +/* + MDNSResponder::_buildDomainForReverseIP4 + + The IP4 address is stringized by printing the four address bytes into a char buffer in + reverse order and adding 'in-addr.arpa' (eg. 012.789.456.123.in-addr.arpa). Used while + detecting reverse IP4 questions and answering these +*/ +bool MDNSResponder::_buildDomainForReverseIP4( + IPAddress p_IP4Address, MDNSResponder::stcMDNS_RRDomain& p_rReverseIP4Domain) const { + bool bResult = true; + + p_rReverseIP4Domain.clear(); + + char acBuffer[32]; + for (int i = MDNS_IP4_SIZE; ((bResult) && (i >= 1)); --i) { + itoa(p_IP4Address[i - 1], acBuffer, 10); + bResult = p_rReverseIP4Domain.addLabel(acBuffer); + } + bResult = ((bResult) && (p_rReverseIP4Domain.addLabel(scpcReverseIP4Domain)) + && (p_rReverseIP4Domain.addLabel(scpcReverseTopDomain)) + && (p_rReverseIP4Domain.addLabel(0))); + DEBUG_EX_ERR(if (!bResult) DEBUG_OUTPUT.printf_P( + PSTR("[MDNSResponder] _buildDomainForReverseIP4: FAILED!\n"));); + return bResult; +} +#endif + +#ifdef MDNS_IP6_SUPPORT +/* + MDNSResponder::_buildDomainForReverseIP6 + + Used while detecting reverse IP6 questions and answering these +*/ +bool MDNSResponder::_buildDomainForReverseIP6( + IPAddress p_IP4Address, MDNSResponder::stcMDNS_RRDomain& p_rReverseIP6Domain) const { + // TODO: Implement + return false; +} +#endif + +/* + UDP +*/ + +/* + MDNSResponder::_udpReadBuffer +*/ +bool MDNSResponder::_udpReadBuffer(unsigned char* p_pBuffer, size_t p_stLength) { + bool bResult = ((m_pUDPContext) && (true /*m_pUDPContext->getSize() > p_stLength*/) + && (p_pBuffer) && (p_stLength) + && ((p_stLength == m_pUDPContext->read((char*)p_pBuffer, p_stLength)))); + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _udpReadBuffer: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_udpRead8 +*/ +bool MDNSResponder::_udpRead8(uint8_t& p_ru8Value) { + return _udpReadBuffer((unsigned char*)&p_ru8Value, sizeof(p_ru8Value)); +} + +/* + MDNSResponder::_udpRead16 +*/ +bool MDNSResponder::_udpRead16(uint16_t& p_ru16Value) { + bool bResult = false; + + if (_udpReadBuffer((unsigned char*)&p_ru16Value, sizeof(p_ru16Value))) { + p_ru16Value = lwip_ntohs(p_ru16Value); + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::_udpRead32 +*/ +bool MDNSResponder::_udpRead32(uint32_t& p_ru32Value) { + bool bResult = false; + + if (_udpReadBuffer((unsigned char*)&p_ru32Value, sizeof(p_ru32Value))) { + p_ru32Value = lwip_ntohl(p_ru32Value); + bResult = true; + } + return bResult; +} + +/* + MDNSResponder::_udpAppendBuffer +*/ +bool MDNSResponder::_udpAppendBuffer(const unsigned char* p_pcBuffer, size_t p_stLength) { + bool bResult + = ((m_pUDPContext) && (p_pcBuffer) && (p_stLength) + && (p_stLength == m_pUDPContext->append((const char*)p_pcBuffer, p_stLength))); + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _udpAppendBuffer: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_udpAppend8 +*/ +bool MDNSResponder::_udpAppend8(uint8_t p_u8Value) { + return (_udpAppendBuffer((unsigned char*)&p_u8Value, sizeof(p_u8Value))); +} + +/* + MDNSResponder::_udpAppend16 +*/ +bool MDNSResponder::_udpAppend16(uint16_t p_u16Value) { + p_u16Value = lwip_htons(p_u16Value); + return (_udpAppendBuffer((unsigned char*)&p_u16Value, sizeof(p_u16Value))); +} + +/* + MDNSResponder::_udpAppend32 +*/ +bool MDNSResponder::_udpAppend32(uint32_t p_u32Value) { + p_u32Value = lwip_htonl(p_u32Value); + return (_udpAppendBuffer((unsigned char*)&p_u32Value, sizeof(p_u32Value))); +} + +#ifdef DEBUG_ESP_MDNS_RESPONDER +/* + MDNSResponder::_udpDump +*/ +bool MDNSResponder::_udpDump(bool p_bMovePointer /*= false*/) { + const uint8_t cu8BytesPerLine = 16; + + uint32_t u32StartPosition = m_pUDPContext->tell(); + DEBUG_OUTPUT.println("UDP Context Dump:"); + uint32_t u32Counter = 0; + uint8_t u8Byte = 0; + + while (_udpRead8(u8Byte)) { + DEBUG_OUTPUT.printf_P(PSTR("%02x %s"), u8Byte, + ((++u32Counter % cu8BytesPerLine) ? "" : "\n")); + } + DEBUG_OUTPUT.printf_P(PSTR("%sDone: %u bytes\n"), + (((u32Counter) && (u32Counter % cu8BytesPerLine)) ? "\n" : ""), + u32Counter); + + if (!p_bMovePointer) { // Restore + m_pUDPContext->seek(u32StartPosition); + } + return true; +} + +/* + MDNSResponder::_udpDump +*/ +bool MDNSResponder::_udpDump(unsigned p_uOffset, unsigned p_uLength) { + if ((m_pUDPContext) && (m_pUDPContext->isValidOffset(p_uOffset))) { + unsigned uCurrentPosition = m_pUDPContext->tell(); // Remember start position + + m_pUDPContext->seek(p_uOffset); + uint8_t u8Byte; + for (unsigned u = 0; ((u < p_uLength) && (_udpRead8(u8Byte))); ++u) { + DEBUG_OUTPUT.printf_P(PSTR("%02x "), u8Byte); + } + // Return to start position + m_pUDPContext->seek(uCurrentPosition); + } + return true; +} +#endif + +/** + READ/WRITE MDNS STRUCTS +*/ + +/* + MDNSResponder::_readMDNSMsgHeader + + Read a MDNS header from the UDP input buffer. + | 8 | 8 | 8 | 8 | + 00| Identifier | Flags & Codes | + 01| Question count | Answer count | + 02| NS answer count | Ad answer count | + + All 16-bit and 32-bit elements need to be translated form network coding to host coding + (done in _udpRead16 and _udpRead32) In addition, bitfield memory order is undefined in C + standard (GCC doesn't order them in the coded direction...), so they need some mapping here +*/ +bool MDNSResponder::_readMDNSMsgHeader(MDNSResponder::stcMDNS_MsgHeader& p_rMsgHeader) { + bool bResult = false; + + uint8_t u8B1; + uint8_t u8B2; + if ((_udpRead16(p_rMsgHeader.m_u16ID)) && (_udpRead8(u8B1)) && (_udpRead8(u8B2)) + && (_udpRead16(p_rMsgHeader.m_u16QDCount)) && (_udpRead16(p_rMsgHeader.m_u16ANCount)) + && (_udpRead16(p_rMsgHeader.m_u16NSCount)) && (_udpRead16(p_rMsgHeader.m_u16ARCount))) { + p_rMsgHeader.m_1bQR = (u8B1 & 0x80); // Query/Respond flag + p_rMsgHeader.m_4bOpcode + = (u8B1 & 0x78); // Operation code (0: Standard query, others ignored) + p_rMsgHeader.m_1bAA = (u8B1 & 0x04); // Authoritative answer + p_rMsgHeader.m_1bTC = (u8B1 & 0x02); // Truncation flag + p_rMsgHeader.m_1bRD = (u8B1 & 0x01); // Recursion desired + + p_rMsgHeader.m_1bRA = (u8B2 & 0x80); // Recursion available + p_rMsgHeader.m_3bZ = (u8B2 & 0x70); // Zero + p_rMsgHeader.m_4bRCode = (u8B2 & 0x0F); // Response code + + /* DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readMDNSMsgHeader: ID:%u + QR:%u OP:%u AA:%u TC:%u RD:%u RA:%u R:%u QD:%u AN:%u NS:%u AR:%u\n"), + (unsigned)p_rMsgHeader.m_u16ID, + (unsigned)p_rMsgHeader.m_1bQR, (unsigned)p_rMsgHeader.m_4bOpcode, + (unsigned)p_rMsgHeader.m_1bAA, (unsigned)p_rMsgHeader.m_1bTC, + (unsigned)p_rMsgHeader.m_1bRD, (unsigned)p_rMsgHeader.m_1bRA, + (unsigned)p_rMsgHeader.m_4bRCode, (unsigned)p_rMsgHeader.m_u16QDCount, + (unsigned)p_rMsgHeader.m_u16ANCount, + (unsigned)p_rMsgHeader.m_u16NSCount, + (unsigned)p_rMsgHeader.m_u16ARCount););*/ + bResult = true; + } + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _readMDNSMsgHeader: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_write8 +*/ +bool MDNSResponder::_write8(uint8_t p_u8Value, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + return ((_udpAppend8(p_u8Value)) && (p_rSendParameter.shiftOffset(sizeof(p_u8Value)))); +} + +/* + MDNSResponder::_write16 +*/ +bool MDNSResponder::_write16(uint16_t p_u16Value, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + return ((_udpAppend16(p_u16Value)) && (p_rSendParameter.shiftOffset(sizeof(p_u16Value)))); +} + +/* + MDNSResponder::_write32 +*/ +bool MDNSResponder::_write32(uint32_t p_u32Value, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + return ((_udpAppend32(p_u32Value)) && (p_rSendParameter.shiftOffset(sizeof(p_u32Value)))); +} + +/* + MDNSResponder::_writeMDNSMsgHeader + + Write MDNS header to the UDP output buffer. + + All 16-bit and 32-bit elements need to be translated form host coding to network coding + (done in _udpAppend16 and _udpAppend32) In addition, bitfield memory order is undefined in C + standard (GCC doesn't order them in the coded direction...), so they need some mapping here +*/ +bool MDNSResponder::_writeMDNSMsgHeader(const MDNSResponder::stcMDNS_MsgHeader& p_MsgHeader, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + /* DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSMsgHeader: ID:%u + QR:%u OP:%u AA:%u TC:%u RD:%u RA:%u R:%u QD:%u AN:%u NS:%u AR:%u\n"), + (unsigned)p_MsgHeader.m_u16ID, + (unsigned)p_MsgHeader.m_1bQR, (unsigned)p_MsgHeader.m_4bOpcode, + (unsigned)p_MsgHeader.m_1bAA, (unsigned)p_MsgHeader.m_1bTC, (unsigned)p_MsgHeader.m_1bRD, + (unsigned)p_MsgHeader.m_1bRA, (unsigned)p_MsgHeader.m_4bRCode, + (unsigned)p_MsgHeader.m_u16QDCount, + (unsigned)p_MsgHeader.m_u16ANCount, + (unsigned)p_MsgHeader.m_u16NSCount, + (unsigned)p_MsgHeader.m_u16ARCount););*/ + + uint8_t u8B1((p_MsgHeader.m_1bQR << 7) | (p_MsgHeader.m_4bOpcode << 3) + | (p_MsgHeader.m_1bAA << 2) | (p_MsgHeader.m_1bTC << 1) + | (p_MsgHeader.m_1bRD)); + uint8_t u8B2((p_MsgHeader.m_1bRA << 7) | (p_MsgHeader.m_3bZ << 4) + | (p_MsgHeader.m_4bRCode)); + bool bResult = ((_write16(p_MsgHeader.m_u16ID, p_rSendParameter)) + && (_write8(u8B1, p_rSendParameter)) && (_write8(u8B2, p_rSendParameter)) + && (_write16(p_MsgHeader.m_u16QDCount, p_rSendParameter)) + && (_write16(p_MsgHeader.m_u16ANCount, p_rSendParameter)) + && (_write16(p_MsgHeader.m_u16NSCount, p_rSendParameter)) + && (_write16(p_MsgHeader.m_u16ARCount, p_rSendParameter))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSMsgHeader: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeRRAttributes +*/ +bool +MDNSResponder::_writeMDNSRRAttributes(const MDNSResponder::stcMDNS_RRAttributes& p_Attributes, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + bool bResult = ((_write16(p_Attributes.m_u16Type, p_rSendParameter)) + && (_write16(p_Attributes.m_u16Class, p_rSendParameter))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSRRAttributes: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeMDNSRRDomain +*/ +bool MDNSResponder::_writeMDNSRRDomain(const MDNSResponder::stcMDNS_RRDomain& p_Domain, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + bool bResult + = ((_udpAppendBuffer((const unsigned char*)p_Domain.m_acName, p_Domain.m_u16NameLength)) + && (p_rSendParameter.shiftOffset(p_Domain.m_u16NameLength))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSRRDomain: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeMDNSHostDomain + + Write a host domain to the UDP output buffer. + If the domain record is part of the answer, the records length is + prepended (p_bPrependRDLength is set). + + A very simple form of name compression is applied here: + If the domain is written to the UDP output buffer, the write offset is stored + together with a domain id (the pointer) in a p_rSendParameter substructure (cache). + If the same domain (pointer) should be written to the UDP output later again, + the old offset is retrieved from the cache, marked as a compressed domain offset + and written to the output buffer. + +*/ +bool MDNSResponder::_writeMDNSHostDomain(const char* p_pcHostname, bool p_bPrependRDLength, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + // The 'skip-compression' version is handled in '_writeMDNSAnswer_SRV' + uint16_t u16CachedDomainOffset + = p_rSendParameter.findCachedDomainOffset((const void*)p_pcHostname, false); + + stcMDNS_RRDomain hostDomain; + bool bResult + = (u16CachedDomainOffset + // Found cached domain -> mark as compressed domain + ? ((MDNS_DOMAIN_COMPRESS_MARK + > ((u16CachedDomainOffset >> 8) & ~MDNS_DOMAIN_COMPRESS_MARK)) + && // Valid offset + ((!p_bPrependRDLength) || (_write16(2, p_rSendParameter))) + && // Length of 'Cxxx' + (_write8(((u16CachedDomainOffset >> 8) | MDNS_DOMAIN_COMPRESS_MARK), + p_rSendParameter)) + && // Compression mark (and offset) + (_write8((uint8_t)(u16CachedDomainOffset & 0xFF), p_rSendParameter))) + // No cached domain -> add this domain to cache and write full domain name + : ((_buildDomainForHost(p_pcHostname, hostDomain)) && // eg. esp8266.local + ((!p_bPrependRDLength) + || (_write16(hostDomain.m_u16NameLength, p_rSendParameter))) + && // RDLength (if needed) + (p_rSendParameter.addDomainCacheItem((const void*)p_pcHostname, false, + p_rSendParameter.m_u16Offset)) + && (_writeMDNSRRDomain(hostDomain, p_rSendParameter)))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSHostDomain: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeMDNSServiceDomain + + Write a service domain to the UDP output buffer. + If the domain record is part of the answer, the records length is + prepended (p_bPrependRDLength is set). + + A very simple form of name compression is applied here: see '_writeMDNSHostDomain' + The cache differentiates of course between service domains which includes + the instance name (p_bIncludeName is set) and thoose who don't. + +*/ +bool +MDNSResponder::_writeMDNSServiceDomain(const MDNSResponder::stcMDNSService& p_Service, + bool p_bIncludeName, bool p_bPrependRDLength, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + // The 'skip-compression' version is handled in '_writeMDNSAnswer_SRV' + uint16_t u16CachedDomainOffset + = p_rSendParameter.findCachedDomainOffset((const void*)&p_Service, p_bIncludeName); + + stcMDNS_RRDomain serviceDomain; + bool bResult + = (u16CachedDomainOffset + // Found cached domain -> mark as compressed domain + ? ((MDNS_DOMAIN_COMPRESS_MARK + > ((u16CachedDomainOffset >> 8) & ~MDNS_DOMAIN_COMPRESS_MARK)) + && // Valid offset + ((!p_bPrependRDLength) || (_write16(2, p_rSendParameter))) + && // Length of 'Cxxx' + (_write8(((u16CachedDomainOffset >> 8) | MDNS_DOMAIN_COMPRESS_MARK), + p_rSendParameter)) + && // Compression mark (and offset) + (_write8((uint8_t)(u16CachedDomainOffset & 0xFF), p_rSendParameter))) + // No cached domain -> add this domain to cache and write full domain name + : ((_buildDomainForService(p_Service, p_bIncludeName, serviceDomain)) + && // eg. MyESP._http._tcp.local + ((!p_bPrependRDLength) + || (_write16(serviceDomain.m_u16NameLength, p_rSendParameter))) + && // RDLength (if needed) + (p_rSendParameter.addDomainCacheItem((const void*)&p_Service, p_bIncludeName, + p_rSendParameter.m_u16Offset)) + && (_writeMDNSRRDomain(serviceDomain, p_rSendParameter)))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSServiceDomain: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeMDNSQuestion + + Write a MDNS question to the UDP output buffer + + QNAME (host/service domain, eg. esp8266.local) + QTYPE (16bit, eg. ANY) + QCLASS (16bit, eg. IN) + +*/ +bool MDNSResponder::_writeMDNSQuestion(MDNSResponder::stcMDNS_RRQuestion& p_Question, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSQuestion\n"));); + + bool bResult + = ((_writeMDNSRRDomain(p_Question.m_Header.m_Domain, p_rSendParameter)) + && (_writeMDNSRRAttributes(p_Question.m_Header.m_Attributes, p_rSendParameter))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSQuestion: FAILED!\n")); + }); + return bResult; +} + +#ifdef MDNS_IP4_SUPPORT +/* + MDNSResponder::_writeMDNSAnswer_A + + Write a MDNS A answer to the UDP output buffer. + + NAME (var, host/service domain, eg. esp8266.local + TYPE (16bit, eg. A) + CLASS (16bit, eg. IN) + TTL (32bit, eg. 120) + RDLENGTH (16bit, eg 4) + RDATA (var, eg. 123.456.789.012) + + eg. esp8266.local A 0x8001 120 4 123.456.789.012 + Ref: http://www.zytrax.com/books/dns/ch8/a.html +*/ +bool MDNSResponder::_writeMDNSAnswer_A(IPAddress p_IPAddress, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_A (%s)\n"), + p_IPAddress.toString().c_str());); + + stcMDNS_RRAttributes attributes(DNS_RRTYPE_A, + ((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0) + | DNS_RRCLASS_IN)); // Cache flush? & INternet + const unsigned char aucIPAddress[MDNS_IP4_SIZE] + = { p_IPAddress[0], p_IPAddress[1], p_IPAddress[2], p_IPAddress[3] }; + bool bResult + = ((_writeMDNSHostDomain(m_pcHostname, false, p_rSendParameter)) + && (_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS + (_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter)) + && // TTL + (_write16(MDNS_IP4_SIZE, p_rSendParameter)) && // RDLength + (_udpAppendBuffer(aucIPAddress, MDNS_IP4_SIZE)) && // RData + (p_rSendParameter.shiftOffset(MDNS_IP4_SIZE))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_A: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeMDNSAnswer_PTR_IP4 + + Write a MDNS reverse IP4 PTR answer to the UDP output buffer. + See: '_writeMDNSAnswer_A' + + eg. 012.789.456.123.in-addr.arpa PTR 0x8001 120 15 esp8266.local + Used while answering reverse IP4 questions +*/ +bool +MDNSResponder::_writeMDNSAnswer_PTR_IP4(IPAddress p_IPAddress, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_PTR_IP4 (%s)\n"), + p_IPAddress.toString().c_str());); + + stcMDNS_RRDomain reverseIP4Domain; + stcMDNS_RRAttributes attributes(DNS_RRTYPE_PTR, + ((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0) + | DNS_RRCLASS_IN)); // Cache flush? & INternet + stcMDNS_RRDomain hostDomain; + bool bResult + = ((_buildDomainForReverseIP4(p_IPAddress, reverseIP4Domain)) + && // 012.789.456.123.in-addr.arpa + (_writeMDNSRRDomain(reverseIP4Domain, p_rSendParameter)) + && (_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS + (_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter)) + && // TTL + (_writeMDNSHostDomain( + m_pcHostname, true, + p_rSendParameter))); // RDLength & RData (host domain, eg. esp8266.local) + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_PTR_IP4: FAILED!\n")); + }); + return bResult; +} +#endif + +/* + MDNSResponder::_writeMDNSAnswer_PTR_TYPE + + Write a MDNS PTR answer to the UDP output buffer. + See: '_writeMDNSAnswer_A' + + PTR all-services -> service type + eg. _services._dns-sd._udp.local PTR 0x8001 5400 xx _http._tcp.local + http://www.zytrax.com/books/dns/ch8/ptr.html +*/ +bool +MDNSResponder::_writeMDNSAnswer_PTR_TYPE(MDNSResponder::stcMDNSService& p_rService, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_PTR_TYPE\n"));); + + stcMDNS_RRDomain dnssdDomain; + stcMDNS_RRDomain serviceDomain; + stcMDNS_RRAttributes attributes(DNS_RRTYPE_PTR, + DNS_RRCLASS_IN); // No cache flush! only INternet + bool bResult + = ((_buildDomainForDNSSD(dnssdDomain)) && // _services._dns-sd._udp.local + (_writeMDNSRRDomain(dnssdDomain, p_rSendParameter)) + && (_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS + (_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_SERVICE_TTL), p_rSendParameter)) + && // TTL + (_writeMDNSServiceDomain( + p_rService, false, true, + p_rSendParameter))); // RDLength & RData (service domain, eg. _http._tcp.local) + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_PTR_TYPE: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeMDNSAnswer_PTR_NAME + + Write a MDNS PTR answer to the UDP output buffer. + See: '_writeMDNSAnswer_A' + + PTR service type -> service name + eg. _http.tcp.local PTR 0x8001 120 xx myESP._http._tcp.local + http://www.zytrax.com/books/dns/ch8/ptr.html +*/ +bool +MDNSResponder::_writeMDNSAnswer_PTR_NAME(MDNSResponder::stcMDNSService& p_rService, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_PTR_NAME\n"));); + + stcMDNS_RRAttributes attributes(DNS_RRTYPE_PTR, + DNS_RRCLASS_IN); // No cache flush! only INternet + bool bResult + = ((_writeMDNSServiceDomain(p_rService, false, false, p_rSendParameter)) + && // _http._tcp.local + (_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS + (_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_SERVICE_TTL), p_rSendParameter)) + && // TTL + (_writeMDNSServiceDomain(p_rService, true, true, + p_rSendParameter))); // RDLength & RData (service domain, + // eg. MyESP._http._tcp.local) + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_PTR_NAME: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeMDNSAnswer_TXT + + Write a MDNS TXT answer to the UDP output buffer. + See: '_writeMDNSAnswer_A' + + The TXT items in the RDATA block are 'length byte encoded': [len]vardata + + eg. myESP._http._tcp.local TXT 0x8001 120 4 c#=1 + http://www.zytrax.com/books/dns/ch8/txt.html +*/ +bool MDNSResponder::_writeMDNSAnswer_TXT(MDNSResponder::stcMDNSService& p_rService, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_TXT\n"));); + + bool bResult = false; + + stcMDNS_RRAttributes attributes(DNS_RRTYPE_TXT, + ((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0) + | DNS_RRCLASS_IN)); // Cache flush? & INternet + + if ((_collectServiceTxts(p_rService)) + && (_writeMDNSServiceDomain(p_rService, true, false, p_rSendParameter)) + && // MyESP._http._tcp.local + (_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS + (_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_SERVICE_TTL), p_rSendParameter)) + && // TTL + (_write16(p_rService.m_Txts.length(), p_rSendParameter))) { // RDLength + bResult = true; + // RData Txts + for (stcMDNSServiceTxt* pTxt = p_rService.m_Txts.m_pTxts; ((bResult) && (pTxt)); + pTxt = pTxt->m_pNext) { + unsigned char ucLengthByte = pTxt->length(); + bResult = ((_udpAppendBuffer((unsigned char*)&ucLengthByte, sizeof(ucLengthByte))) + && // Length + (p_rSendParameter.shiftOffset(sizeof(ucLengthByte))) + && ((size_t)strlen(pTxt->m_pcKey) + == m_pUDPContext->append(pTxt->m_pcKey, strlen(pTxt->m_pcKey))) + && // Key + (p_rSendParameter.shiftOffset((size_t)strlen(pTxt->m_pcKey))) + && (1 == m_pUDPContext->append("=", 1)) && // = + (p_rSendParameter.shiftOffset(1)) + && ((!pTxt->m_pcValue) + || (((size_t)strlen(pTxt->m_pcValue) + == m_pUDPContext->append(pTxt->m_pcValue, + strlen(pTxt->m_pcValue))) + && // Value + (p_rSendParameter.shiftOffset( + (size_t)strlen(pTxt->m_pcValue)))))); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P( + PSTR( + "[MDNSResponder] _writeMDNSAnswer_TXT: FAILED to write %sTxt %s=%s!\n"), + (pTxt->m_bTemp ? "temp. " : ""), (pTxt->m_pcKey ? : "?"), + (pTxt->m_pcValue ? : "?")); + }); + } + } + _releaseTempServiceTxts(p_rService); + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_TXT: FAILED!\n")); + }); + return bResult; +} + +#ifdef MDNS_IP6_SUPPORT +/* + MDNSResponder::_writeMDNSAnswer_AAAA + + Write a MDNS AAAA answer to the UDP output buffer. + See: '_writeMDNSAnswer_A' + + eg. esp8266.local AAAA 0x8001 120 16 xxxx::xx + http://www.zytrax.com/books/dns/ch8/aaaa.html +*/ +bool MDNSResponder::_writeMDNSAnswer_AAAA(IPAddress p_IPAddress, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_AAAA\n"));); + + stcMDNS_RRAttributes attributes(DNS_RRTYPE_AAAA, + ((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0) + | DNS_RRCLASS_IN)); // Cache flush? & INternet + bool bResult + = ((_writeMDNSHostDomain(m_pcHostname, false, p_rSendParameter)) && // esp8266.local + (_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS + (_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter)) + && // TTL + (_write16(MDNS_IP6_SIZE, p_rSendParameter)) && // RDLength + (false /*TODO: IP6 version of: _udpAppendBuffer((uint32_t)p_IPAddress, MDNS_IP4_SIZE)*/)); // RData + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_AAAA: FAILED!\n")); + }); + return bResult; +} + +/* + MDNSResponder::_writeMDNSAnswer_PTR_IP6 + + Write a MDNS reverse IP6 PTR answer to the UDP output buffer. + See: '_writeMDNSAnswer_A' + + eg. xxxx::xx.in6.arpa PTR 0x8001 120 15 esp8266.local + Used while answering reverse IP6 questions +*/ +bool +MDNSResponder::_writeMDNSAnswer_PTR_IP6(IPAddress p_IPAddress, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_PTR_IP6\n"));); + + stcMDNS_RRDomain reverseIP6Domain; + stcMDNS_RRAttributes attributes(DNS_RRTYPE_PTR, + ((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0) + | DNS_RRCLASS_IN)); // Cache flush? & INternet + bool bResult + = ((_buildDomainForReverseIP6(p_IPAddress, reverseIP6Domain)) && // xxxx::xx.ip6.arpa + (_writeMDNSRRDomain(reverseIP6Domain, p_rSendParameter)) + && (_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS + (_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_HOST_TTL), p_rSendParameter)) + && // TTL + (_writeMDNSHostDomain( + m_pcHostname, true, + p_rSendParameter))); // RDLength & RData (host domain, eg. esp8266.local) + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_PTR_IP6: FAILED!\n")); + }); + return bResult; +} +#endif + +/* + MDNSResponder::_writeMDNSAnswer_SRV + + eg. MyESP._http.tcp.local SRV 0x8001 120 0 0 60068 esp8266.local + http://www.zytrax.com/books/dns/ch8/srv.html ???? Include instance name ???? +*/ +bool MDNSResponder::_writeMDNSAnswer_SRV(MDNSResponder::stcMDNSService& p_rService, + MDNSResponder::stcMDNSSendParameter& p_rSendParameter) { + DEBUG_EX_INFO(DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_SRV\n"));); + + uint16_t u16CachedDomainOffset + = (p_rSendParameter.m_bLegacyQuery + ? 0 + : p_rSendParameter.findCachedDomainOffset((const void*)m_pcHostname, false)); + + stcMDNS_RRAttributes attributes(DNS_RRTYPE_SRV, + ((p_rSendParameter.m_bCacheFlush ? 0x8000 : 0) + | DNS_RRCLASS_IN)); // Cache flush? & INternet + stcMDNS_RRDomain hostDomain; + bool bResult + = ((_writeMDNSServiceDomain(p_rService, true, false, p_rSendParameter)) + && // MyESP._http._tcp.local + (_writeMDNSRRAttributes(attributes, p_rSendParameter)) && // TYPE & CLASS + (_write32((p_rSendParameter.m_bUnannounce ? 0 : MDNS_SERVICE_TTL), p_rSendParameter)) + && // TTL + (!u16CachedDomainOffset + // No cache for domain name (or no compression allowed) + ? ((_buildDomainForHost(m_pcHostname, hostDomain)) + && (_write16((sizeof(uint16_t /*Prio*/) + // RDLength + sizeof(uint16_t /*Weight*/) + sizeof(uint16_t /*Port*/) + + hostDomain.m_u16NameLength), + p_rSendParameter)) + && // Domain length + (_write16(MDNS_SRV_PRIORITY, p_rSendParameter)) && // Priority + (_write16(MDNS_SRV_WEIGHT, p_rSendParameter)) && // Weight + (_write16(p_rService.m_u16Port, p_rSendParameter)) && // Port + (p_rSendParameter.addDomainCacheItem((const void*)m_pcHostname, false, + p_rSendParameter.m_u16Offset)) + && (_writeMDNSRRDomain(hostDomain, + p_rSendParameter))) // Host, eg. esp8266.local + // Cache available for domain + : ((MDNS_DOMAIN_COMPRESS_MARK + > ((u16CachedDomainOffset >> 8) & ~MDNS_DOMAIN_COMPRESS_MARK)) + && // Valid offset + (_write16((sizeof(uint16_t /*Prio*/) + // RDLength + sizeof(uint16_t /*Weight*/) + sizeof(uint16_t /*Port*/) + 2), + p_rSendParameter)) + && // Length of 'C0xx' + (_write16(MDNS_SRV_PRIORITY, p_rSendParameter)) && // Priority + (_write16(MDNS_SRV_WEIGHT, p_rSendParameter)) && // Weight + (_write16(p_rService.m_u16Port, p_rSendParameter)) && // Port + (_write8(((u16CachedDomainOffset >> 8) | MDNS_DOMAIN_COMPRESS_MARK), + p_rSendParameter)) + && // Compression mark (and offset) + (_write8((uint8_t)u16CachedDomainOffset, p_rSendParameter))))); // Offset + + DEBUG_EX_ERR(if (!bResult) { + DEBUG_OUTPUT.printf_P(PSTR("[MDNSResponder] _writeMDNSAnswer_SRV: FAILED!\n")); + }); + return bResult; +} + +} // namespace MDNSImplementation + +} // namespace esp8266 diff --git a/libraries/LEAmDNS/src/LEAmDNS_lwIPdefs.h b/libraries/LEAmDNS/src/LEAmDNS_lwIPdefs.h new file mode 100644 index 00000000..ea2128a9 --- /dev/null +++ b/libraries/LEAmDNS/src/LEAmDNS_lwIPdefs.h @@ -0,0 +1,30 @@ +/* + LEAmDNS_Priv.h + + License (MIT license): + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#ifndef MDNS_LWIPDEFS_H +#define MDNS_LWIPDEFS_H + +#include // DNS_RRTYPE_xxx, DNS_MQUERY_PORT + +#endif // MDNS_LWIPDEFS_H diff --git a/libraries/LittleFS/keywords.txt b/libraries/LittleFS/keywords.txt new file mode 100644 index 00000000..850eded9 --- /dev/null +++ b/libraries/LittleFS/keywords.txt @@ -0,0 +1,20 @@ +####################################### +# Syntax Coloring Map For Ultrasound +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +LittleFS KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +format KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/MD5Builder/keywords.txt b/libraries/MD5Builder/keywords.txt new file mode 100644 index 00000000..07813bc6 --- /dev/null +++ b/libraries/MD5Builder/keywords.txt @@ -0,0 +1,27 @@ +####################################### +# Syntax Coloring Map For Ultrasound +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +MD5Builder KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +add KEYWORD2 +addHexString KEYWORD2 +addStream KEYWORD2 +calculate KEYWORD2 +getBytes KEYWORD2 +getChars KEYWORD2 +toString KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/MD5Builder/library.properties b/libraries/MD5Builder/library.properties new file mode 100644 index 00000000..485a13bc --- /dev/null +++ b/libraries/MD5Builder/library.properties @@ -0,0 +1,10 @@ +name=MD5Builder +version=1.0.0 +author=Earle F. Philhower, III +maintainer=Earle F. Philhower, III +sentence=Allows generating MD5 hashes of streams +paragraph=Allows generating MD5 hashes of streams +category=Data Processing +url=https://github.com/earlephilhower/arduino-pico +architectures=rp2040 +dot_a_linkage=true diff --git a/libraries/MD5Builder/src/MD5Builder.cpp b/libraries/MD5Builder/src/MD5Builder.cpp new file mode 100644 index 00000000..6cd9060e --- /dev/null +++ b/libraries/MD5Builder/src/MD5Builder.cpp @@ -0,0 +1,117 @@ +/* + MD5Builder - Simple MD5 hash calculations + + Updated for the Pico by Earle F. Philhower, III + + Modified from the ESP8266 version which is + Copyright (c) 2015 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include + +static uint8_t hex_char_to_byte(uint8_t c) { + return (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) : + (c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) : + (c >= '0' && c <= '9') ? (c - (uint8_t)'0') : 0; +} + +void MD5Builder::begin(void) { + memset(_buf, 0x00, 16); + br_md5_init(&_ctx); +} + +void MD5Builder::add(const uint8_t * data, const uint16_t len) { + br_md5_update(&_ctx, data, len); +} + +void MD5Builder::addHexString(const char * data) { + uint16_t i, len = strlen(data); + auto tmp = std::unique_ptr {new (std::nothrow) uint8_t[len / 2]}; + + if (!tmp) { + return; + } + + for (i = 0; i < len; i += 2) { + uint8_t high = hex_char_to_byte(data[i]); + uint8_t low = hex_char_to_byte(data[i + 1]); + tmp[i / 2] = (high & 0x0F) << 4 | (low & 0x0F); + } + add(tmp.get(), len / 2); +} + +bool MD5Builder::addStream(Stream &stream, const size_t maxLen) { + const int buf_size = 512; + int maxLengthLeft = maxLen; + + auto buf = std::unique_ptr {new (std::nothrow) uint8_t[buf_size]}; + + if (!buf) { + return false; + } + + int bytesAvailable = stream.available(); + while ((bytesAvailable > 0) && (maxLengthLeft > 0)) { + + // determine number of bytes to read + int readBytes = bytesAvailable; + if (readBytes > maxLengthLeft) { + readBytes = maxLengthLeft; // read only until max_len + } + if (readBytes > buf_size) { + readBytes = buf_size; // not read more the buffer can handle + } + + // read data and check if we got something + int numBytesRead = stream.readBytes(buf.get(), readBytes); + if (numBytesRead < 1) { + return false; + } + + // Update MD5 with buffer payload + br_md5_update(&_ctx, buf.get(), numBytesRead); + + // update available number of bytes + maxLengthLeft -= numBytesRead; + bytesAvailable = stream.available(); + } + + return true; +} + +void MD5Builder::calculate(void) { + br_md5_out(&_ctx, _buf); +} + +void MD5Builder::getBytes(uint8_t * output) const { + memcpy(output, _buf, 16); +} + +void MD5Builder::getChars(char * output) const { + for (uint8_t i = 0; i < 16; i++) { + sprintf(output + (i * 2), "%02x", _buf[i]); + } +} + +String MD5Builder::toString(void) const { + char out[33]; + getChars(out); + return String(out); +} diff --git a/libraries/MD5Builder/src/MD5Builder.h b/libraries/MD5Builder/src/MD5Builder.h new file mode 100644 index 00000000..978d8709 --- /dev/null +++ b/libraries/MD5Builder/src/MD5Builder.h @@ -0,0 +1,59 @@ +/* + MD5Builder - Simple MD5 hash calculations + + Updated for the Pico by Earle F. Philhower, III + + Modified from the ESP8266 version which is + Copyright (c) 2015 Hristo Gochkov. All rights reserved. + This file is part of the esp8266 core for Arduino environment. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include +#include + +class MD5Builder { +private: + br_md5_context _ctx; + uint8_t _buf[16]; +public: + void begin(void); + void add(const uint8_t * data, const uint16_t len); + void add(const char * data) { + add((const uint8_t*)data, strlen(data)); + } + void add(char * data) { + add((const char*)data); + } + void add(const String& data) { + add(data.c_str()); + } + void addHexString(const char * data); + void addHexString(char * data) { + addHexString((const char*)data); + } + void addHexString(const String& data) { + addHexString(data.c_str()); + } + bool addStream(Stream & stream, const size_t maxLen); + void calculate(void); + void getBytes(uint8_t * output) const; + void getChars(char * output) const; + String toString(void) const; +}; diff --git a/libraries/PicoOTA/examples/OTAfromFile-Compressed/OTAfromFile-Compressed.ino b/libraries/PicoOTA/examples/OTAfromFile-Compressed/OTAfromFile-Compressed.ino new file mode 100644 index 00000000..30e0d2ad --- /dev/null +++ b/libraries/PicoOTA/examples/OTAfromFile-Compressed/OTAfromFile-Compressed.ino @@ -0,0 +1,42 @@ +// This example overwrites itself with a serial blinker sketch using OTA +// In general, you will get a file from the Internet, over a serial port, etc. +// and not include it in a header like we do here for simplicity. +// +// The blinker.BIN file was compressed with `gzip -9` and will be expanded +// during OTA +// +// You need to have at least 256K of filesystem configured in +// Tools->Flash Size +// +// Released to the public domain August 2022 by Earle F. Philhower, III + +#include +#include +#include "blink_100_1000.h" + +void setup() { + Serial.begin(115200); + delay(5000); + + Serial.printf("Writing OTA image of blinker..."); + LittleFS.begin(); + File f = LittleFS.open("blink.bin.gz", "w"); + if (sizeof(blink_gz) != f.write(blink_gz, sizeof(blink_gz))) { + Serial.printf("Unable to write OTA binary. Is the filesystem size set?\n"); + return; + } + f.close(); + Serial.printf("done\n\n"); + Serial.printf("Programming OTA commands..."); + picoOTA.begin(); + picoOTA.addFile("blink.bin.gz"); + picoOTA.commit(); + LittleFS.end(); + Serial.printf("done\n\n"); + Serial.printf("Rebooting in 5 seconds, should begin blinker instead of this app...\n"); + delay(5000); + rp2040.reboot(); +} + +void loop() { +} diff --git a/libraries/PicoOTA/examples/OTAfromFile-Compressed/blink_100_1000.h b/libraries/PicoOTA/examples/OTAfromFile-Compressed/blink_100_1000.h new file mode 100644 index 00000000..19f6d1aa --- /dev/null +++ b/libraries/PicoOTA/examples/OTAfromFile-Compressed/blink_100_1000.h @@ -0,0 +1,3898 @@ +const unsigned char blink_gz[] = { + 0x1f, 0x8b, 0x08, 0x08, 0x86, 0x7e, 0xf3, 0x62, 0x02, 0x03, 0x73, 0x6b, + 0x65, 0x74, 0x63, 0x68, 0x5f, 0x61, 0x75, 0x67, 0x31, 0x30, 0x61, 0x2e, + 0x69, 0x6e, 0x6f, 0x2e, 0x62, 0x69, 0x6e, 0x00, 0xec, 0xfd, 0x79, 0x7c, + 0x54, 0xd5, 0xf9, 0x38, 0x8e, 0x3f, 0xe7, 0xce, 0x9d, 0x35, 0x93, 0x64, + 0xb2, 0x00, 0x77, 0x66, 0xb2, 0xcc, 0xcc, 0x4d, 0x42, 0x92, 0x01, 0x9c, + 0x64, 0x40, 0x81, 0xa8, 0x0c, 0x77, 0x30, 0x24, 0x19, 0x50, 0x04, 0x6d, + 0x59, 0xd4, 0x4e, 0x12, 0xc4, 0x09, 0xeb, 0x00, 0x2e, 0x43, 0xb5, 0x25, + 0x80, 0xb6, 0x2c, 0xb6, 0x0d, 0x19, 0xd4, 0x64, 0x2e, 0x22, 0x12, 0x6d, + 0xd9, 0xac, 0x34, 0x1a, 0xbb, 0x68, 0x6a, 0xdc, 0x5a, 0xa9, 0x6d, 0xbd, + 0x97, 0xa5, 0x0d, 0x04, 0x6a, 0x58, 0xc7, 0xba, 0x75, 0x2a, 0xea, 0x64, + 0x9f, 0xdf, 0x73, 0xee, 0x04, 0xa5, 0x7d, 0xf7, 0xfb, 0xf9, 0x7c, 0xbe, + 0x7f, 0x7d, 0x7f, 0xaf, 0xef, 0xb7, 0xc9, 0xeb, 0xce, 0x3d, 0xfb, 0x79, + 0xce, 0x73, 0x9e, 0xf3, 0x2c, 0xe7, 0x9e, 0x05, 0x3a, 0xca, 0x7d, 0x76, + 0xdb, 0x42, 0x7f, 0x4b, 0x80, 0xb1, 0x6f, 0xf5, 0xb6, 0xf8, 0xbb, 0xfd, + 0x5c, 0xed, 0xc2, 0xda, 0x49, 0x3e, 0xb0, 0xb7, 0xfa, 0x19, 0xfb, 0xa2, + 0x5a, 0x62, 0x8f, 0x39, 0x5a, 0xe7, 0x39, 0xab, 0xcd, 0x7e, 0x82, 0x21, + 0x53, 0x6c, 0x10, 0x9b, 0xd5, 0xc7, 0x38, 0x9a, 0x84, 0x6c, 0x49, 0x63, + 0x37, 0x2f, 0x83, 0xd8, 0xe4, 0x3e, 0xf3, 0x6a, 0x42, 0x5d, 0x36, 0x6e, + 0x99, 0x05, 0xfd, 0x13, 0xd0, 0x4f, 0xff, 0xd5, 0x98, 0xf2, 0xba, 0x3e, + 0x62, 0xd7, 0x09, 0xfd, 0x32, 0x2d, 0xcb, 0x8a, 0x25, 0x80, 0x7d, 0x91, + 0xdf, 0x52, 0x6d, 0xad, 0x22, 0x4a, 0x59, 0x1f, 0x63, 0xae, 0xbd, 0x4a, + 0x19, 0x99, 0x7d, 0x34, 0xc5, 0xd8, 0xea, 0xec, 0xd1, 0x18, 0xf2, 0x1a, + 0x14, 0x83, 0x04, 0xb3, 0x33, 0xab, 0xb2, 0xaa, 0x75, 0x7e, 0xd5, 0xbb, + 0x8d, 0x57, 0x74, 0x5b, 0x75, 0xb3, 0x55, 0x1d, 0xad, 0xcb, 0x59, 0x1b, + 0x11, 0x06, 0x25, 0x82, 0xbf, 0x7d, 0xb2, 0xaa, 0x93, 0xe9, 0xe0, 0x96, + 0x71, 0xcb, 0x12, 0xf1, 0xcf, 0x13, 0xdc, 0x6a, 0x6e, 0x35, 0xd3, 0x09, + 0xc0, 0x78, 0x00, 0x80, 0x03, 0xd0, 0x02, 0xa8, 0xbe, 0x03, 0x76, 0x07, + 0xc0, 0x17, 0xe8, 0x77, 0xd8, 0x60, 0x2f, 0x10, 0x30, 0xe9, 0x3e, 0x85, + 0x5e, 0xb8, 0xe6, 0xef, 0xfe, 0xf6, 0x5b, 0xbf, 0x0b, 0x36, 0xd6, 0x16, + 0xc7, 0xb8, 0xb7, 0xf0, 0x79, 0x07, 0x9f, 0x37, 0xfe, 0x17, 0xcf, 0xef, + 0xaf, 0x71, 0x1f, 0xc5, 0xe7, 0x3d, 0x7c, 0xfe, 0xf4, 0xff, 0xf0, 0x03, + 0xbf, 0xbd, 0xe6, 0x3f, 0x76, 0x7b, 0x9f, 0x69, 0x2a, 0xfc, 0xf6, 0xf3, + 0x8f, 0xb7, 0xae, 0xed, 0x65, 0xc0, 0x34, 0x84, 0xcf, 0x64, 0x7c, 0x9a, + 0xda, 0x2c, 0x51, 0xb0, 0x15, 0x20, 0x2e, 0x35, 0xef, 0x6e, 0x42, 0x5c, + 0x9a, 0x66, 0x3b, 0xaa, 0x20, 0x00, 0xc5, 0x53, 0xe4, 0xd4, 0xe7, 0xd2, + 0xfe, 0x08, 0x25, 0x8c, 0x44, 0xfb, 0xa0, 0x3f, 0x9a, 0x5b, 0x9d, 0x57, + 0x03, 0x36, 0xe8, 0x25, 0x6f, 0xec, 0x14, 0x86, 0xe4, 0x9c, 0xea, 0xad, + 0xb3, 0xaf, 0x3e, 0xf0, 0xdb, 0xe1, 0x28, 0x39, 0x4a, 0xde, 0x8c, 0x08, + 0x83, 0xc7, 0x83, 0xb3, 0x69, 0xb9, 0x5d, 0x00, 0xb6, 0x23, 0x0e, 0xb0, + 0x7d, 0x52, 0x00, 0x26, 0xfa, 0x7e, 0xad, 0x10, 0x6c, 0x7d, 0xe3, 0x11, + 0x1e, 0x60, 0x6d, 0xf4, 0x51, 0xdc, 0x26, 0x74, 0xd3, 0x07, 0xff, 0x82, + 0xb3, 0x53, 0xaa, 0x20, 0xc6, 0xf5, 0xc1, 0xec, 0x7f, 0x5c, 0x51, 0x37, + 0x76, 0xb5, 0x07, 0x67, 0x03, 0x8c, 0xf6, 0x87, 0x44, 0xf3, 0xfe, 0xf1, + 0x24, 0xd8, 0x1e, 0xcb, 0x03, 0xdb, 0xdd, 0x04, 0x6c, 0xad, 0xf8, 0x7c, + 0xfb, 0x5b, 0xc9, 0x3e, 0x22, 0x2f, 0x33, 0x55, 0x8f, 0x56, 0x92, 0xd7, + 0xfc, 0xb3, 0xe1, 0xf5, 0xd4, 0x1c, 0xb0, 0x69, 0x60, 0xfe, 0xbc, 0x43, + 0x2f, 0xf9, 0x17, 0xd8, 0x0b, 0x93, 0xee, 0x1f, 0xe4, 0xa8, 0x98, 0x09, + 0xa3, 0xee, 0x3b, 0x1c, 0xfb, 0x9e, 0x76, 0xa1, 0x5b, 0x8d, 0xee, 0xbf, + 0xdd, 0xfb, 0x45, 0x80, 0xc2, 0x70, 0x02, 0x61, 0x7d, 0x17, 0x9f, 0xd7, + 0xf0, 0xb9, 0x11, 0xe3, 0x8e, 0xe0, 0xbb, 0x0a, 0xdf, 0x77, 0x50, 0x78, + 0x3b, 0xba, 0x2a, 0xd9, 0x2a, 0xb5, 0xcf, 0xd4, 0xb1, 0x45, 0x50, 0x49, + 0xac, 0x0f, 0x9c, 0x20, 0xb5, 0xcc, 0x36, 0x75, 0x52, 0x78, 0xe8, 0x43, + 0xeb, 0xd7, 0x54, 0x69, 0xab, 0xf5, 0x96, 0x1d, 0xa6, 0xa3, 0xe9, 0x47, + 0x39, 0x53, 0x47, 0xb5, 0xe9, 0xff, 0x2a, 0x9d, 0xa9, 0x43, 0x3b, 0x87, + 0x0f, 0x81, 0x53, 0x2f, 0x27, 0xe2, 0x27, 0x13, 0x6a, 0x4c, 0xc3, 0x48, + 0x6c, 0x15, 0xb6, 0xef, 0x75, 0xc2, 0xf3, 0xc1, 0x64, 0x5a, 0x9a, 0x8e, + 0xe2, 0x8a, 0xd6, 0x08, 0x4e, 0x2c, 0xa9, 0x5a, 0xad, 0xa4, 0x48, 0xc4, + 0xff, 0x98, 0x30, 0x75, 0x76, 0x55, 0xd2, 0xf8, 0xae, 0xc2, 0x24, 0x5e, + 0x8f, 0x74, 0x6c, 0x3e, 0x02, 0x2f, 0x86, 0xfc, 0xd3, 0xfc, 0x10, 0x33, + 0xf7, 0xe9, 0x7c, 0xba, 0x9a, 0x88, 0x5f, 0xeb, 0xcb, 0x0d, 0x68, 0x7d, + 0xd6, 0x40, 0x0e, 0x02, 0xf0, 0x74, 0xe5, 0xde, 0xd9, 0xc0, 0x73, 0xd0, + 0x59, 0xc9, 0x1c, 0x39, 0x42, 0xf3, 0x52, 0x5c, 0x7a, 0x10, 0xdb, 0xf8, + 0x8c, 0x44, 0x11, 0xdf, 0x1d, 0x73, 0xaa, 0x75, 0x8e, 0x39, 0x55, 0x3f, + 0x38, 0x42, 0x62, 0xbf, 0x4e, 0xd4, 0x54, 0x43, 0xb1, 0x47, 0x26, 0xbc, + 0x01, 0x48, 0x41, 0xd5, 0xdc, 0x25, 0xc2, 0xd8, 0xd0, 0x7a, 0x8f, 0xae, + 0x88, 0x83, 0x25, 0x3a, 0x9b, 0x07, 0xa4, 0x15, 0x1e, 0x72, 0x33, 0x4c, + 0x8a, 0xcb, 0x42, 0x15, 0x29, 0xdf, 0x2c, 0xc4, 0xe4, 0x9f, 0x3a, 0x7a, + 0xbc, 0xcd, 0xb0, 0x7d, 0x61, 0x44, 0x28, 0x92, 0x7d, 0x0d, 0xe0, 0xe4, + 0xa5, 0x9f, 0x39, 0x6e, 0x9c, 0x33, 0xad, 0xba, 0x19, 0x9b, 0x40, 0x62, + 0xdb, 0x13, 0x8e, 0x86, 0x73, 0x81, 0xbd, 0x01, 0x88, 0xbd, 0xdf, 0x07, + 0xc5, 0x63, 0xa4, 0xc6, 0xc2, 0x55, 0x64, 0x8a, 0x6f, 0x49, 0xc3, 0x4b, + 0x42, 0x46, 0xf7, 0x3f, 0xae, 0x98, 0x1e, 0x5d, 0xf7, 0x4a, 0xa3, 0xbd, + 0xcb, 0x56, 0x4d, 0x1a, 0x09, 0x13, 0x5b, 0xd6, 0xf7, 0xe8, 0x15, 0xd3, + 0x56, 0xb0, 0x2f, 0x75, 0xe8, 0x30, 0xe7, 0x95, 0x61, 0xcd, 0x91, 0x60, + 0x67, 0x5b, 0x03, 0x71, 0x66, 0xc9, 0x36, 0xc8, 0x71, 0x41, 0x0c, 0xfa, + 0xa1, 0xf8, 0x0b, 0xa9, 0x77, 0x15, 0xc4, 0x6e, 0x43, 0xd7, 0x3f, 0x24, + 0x7e, 0x35, 0x84, 0xeb, 0x57, 0x93, 0x30, 0x88, 0xe0, 0x64, 0x65, 0x88, + 0xed, 0xee, 0x27, 0xd7, 0xcf, 0x9b, 0xfc, 0x7e, 0x14, 0x44, 0x26, 0x7c, + 0x48, 0x80, 0x53, 0xcc, 0x13, 0x4c, 0x0b, 0xc4, 0x56, 0xf4, 0xab, 0x9a, + 0xa0, 0xb8, 0x5b, 0x2a, 0x05, 0xd2, 0x4a, 0x62, 0x35, 0x09, 0x0a, 0x05, + 0xd6, 0xbc, 0x45, 0x1d, 0x5e, 0xf7, 0x4a, 0xcc, 0x91, 0xa9, 0xd9, 0x55, + 0x49, 0xc4, 0x12, 0xa8, 0x9f, 0xc5, 0x01, 0x1b, 0x66, 0x62, 0x05, 0x7d, + 0xa5, 0xa0, 0x6a, 0x65, 0x5b, 0x98, 0xd8, 0x92, 0x3e, 0xb5, 0xb8, 0x85, + 0xc2, 0x23, 0x32, 0x11, 0xd1, 0xd2, 0xe8, 0x98, 0x4f, 0x76, 0x55, 0x42, + 0x98, 0x88, 0xf5, 0xb3, 0x48, 0xf8, 0x9d, 0x68, 0x57, 0xe5, 0x19, 0x1e, + 0x1b, 0xe8, 0x02, 0x93, 0x6d, 0xcb, 0xaf, 0x3e, 0x6d, 0x29, 0x07, 0xd3, + 0x17, 0x45, 0xe8, 0xb7, 0x05, 0x67, 0xeb, 0xb1, 0xbf, 0x2c, 0x81, 0xdb, + 0xbd, 0xba, 0x1a, 0x53, 0xc0, 0xc3, 0x25, 0xdb, 0x48, 0xeb, 0x31, 0x07, + 0x1a, 0x39, 0x12, 0xfb, 0x22, 0xa1, 0xb4, 0xd1, 0x66, 0xea, 0xec, 0xc6, + 0xbe, 0x6b, 0x2a, 0x01, 0x9b, 0xa1, 0xca, 0xd4, 0xc1, 0x06, 0xe6, 0x78, + 0x9f, 0xe3, 0xf4, 0x98, 0x03, 0xcc, 0xdf, 0xe4, 0x68, 0xe4, 0xcc, 0xc0, + 0x44, 0x98, 0xd8, 0xd8, 0xbe, 0x7f, 0xcf, 0xc3, 0x81, 0x06, 0x6b, 0xc9, + 0x09, 0xa8, 0x7d, 0x73, 0xbc, 0xe6, 0x00, 0xe6, 0x34, 0x33, 0x11, 0x12, + 0x3b, 0x31, 0x72, 0x6d, 0x9a, 0x46, 0x3e, 0xd8, 0xa1, 0x9d, 0xcb, 0x42, + 0x29, 0xa8, 0xfd, 0x9a, 0xea, 0x25, 0x44, 0x53, 0x45, 0x62, 0x15, 0x7d, + 0x7c, 0x60, 0x22, 0xb7, 0x38, 0xe7, 0x5e, 0xbf, 0xc3, 0xcf, 0x85, 0x82, + 0x9d, 0xef, 0x5e, 0x07, 0xb6, 0x33, 0x98, 0xde, 0x55, 0x44, 0xe9, 0x3b, + 0xd7, 0x97, 0x7b, 0x2b, 0xe7, 0xcf, 0xf5, 0xa5, 0x82, 0xd9, 0x3f, 0x0e, + 0xc0, 0x1e, 0x72, 0xb8, 0xb0, 0x1f, 0xda, 0x46, 0x80, 0x37, 0xcf, 0x69, + 0x5b, 0xca, 0xfb, 0xcd, 0xbe, 0x4b, 0xb5, 0xf5, 0x7e, 0xce, 0xd7, 0x86, + 0xcf, 0x05, 0x7c, 0xf8, 0xda, 0x46, 0x7e, 0x09, 0xd4, 0xd7, 0xb6, 0xd5, + 0xc2, 0x44, 0x56, 0x2a, 0x81, 0xa9, 0x98, 0xba, 0x7b, 0x58, 0x0d, 0x26, + 0xbe, 0xbe, 0x2e, 0xe6, 0x6e, 0xab, 0xbb, 0x50, 0x67, 0xf2, 0xb9, 0x80, + 0xaf, 0x37, 0xf9, 0xec, 0x50, 0x5f, 0x9f, 0xee, 0x2b, 0xac, 0x6b, 0xab, + 0x07, 0xfe, 0x42, 0x3d, 0xbf, 0xb4, 0x7e, 0x29, 0xc4, 0x6e, 0x18, 0xe9, + 0xf2, 0x76, 0xa5, 0xf7, 0x75, 0x52, 0x58, 0x69, 0xfd, 0x14, 0xee, 0xfd, + 0xf8, 0x9e, 0xab, 0x02, 0x9b, 0x19, 0x9f, 0xbf, 0x33, 0x60, 0xbb, 0x84, + 0xcf, 0x1f, 0x64, 0x7c, 0x24, 0x7c, 0x8e, 0x21, 0x7e, 0xed, 0xb1, 0x0e, + 0xbb, 0xcf, 0x71, 0x9b, 0x39, 0xe8, 0xb8, 0xd5, 0xe1, 0x7b, 0x0c, 0x87, + 0x27, 0x84, 0xa7, 0x01, 0xe1, 0x5d, 0x00, 0xb1, 0x74, 0xec, 0x59, 0xd5, + 0x69, 0x28, 0x2c, 0x06, 0xf5, 0x91, 0x58, 0x27, 0xc3, 0x4f, 0xc3, 0xce, + 0x51, 0x1d, 0x84, 0xd8, 0x1b, 0x09, 0xa6, 0xf8, 0x8a, 0x4c, 0x7d, 0x24, + 0x76, 0xb4, 0x6f, 0x45, 0xa5, 0xf5, 0x61, 0x52, 0x98, 0xef, 0xfc, 0x58, + 0x5e, 0x51, 0xb9, 0xe4, 0xe1, 0x1d, 0xce, 0xa8, 0x4c, 0x62, 0x9f, 0xf7, + 0x03, 0xdf, 0xe8, 0x48, 0x9f, 0x63, 0xaa, 0xe6, 0xfd, 0xf5, 0xfe, 0x74, + 0x9f, 0x0d, 0x32, 0x99, 0x36, 0x3f, 0x89, 0x45, 0xfb, 0x29, 0x05, 0x2f, + 0x19, 0x84, 0x62, 0x56, 0x4a, 0xe6, 0x3f, 0xd0, 0xf7, 0xe7, 0x28, 0xf1, + 0xe5, 0x06, 0xff, 0x88, 0xfd, 0xff, 0xee, 0xbc, 0x6f, 0x70, 0xb7, 0x12, + 0xdf, 0x5d, 0xa5, 0x08, 0x23, 0x86, 0xad, 0x55, 0x51, 0x5c, 0x66, 0xf9, + 0xd4, 0x90, 0x13, 0x82, 0x09, 0x59, 0x52, 0xe3, 0xf8, 0x8d, 0x04, 0x26, + 0x9a, 0xa5, 0xf4, 0x2a, 0x93, 0x6f, 0x12, 0x78, 0x6b, 0xb7, 0xd4, 0x76, + 0x22, 0x6d, 0xde, 0x0c, 0xa2, 0xf9, 0xad, 0x5a, 0x12, 0x7b, 0xbb, 0x9f, + 0x14, 0xa7, 0x76, 0xbf, 0x60, 0xfd, 0x34, 0xca, 0x03, 0x03, 0xba, 0x6a, + 0x3d, 0xf6, 0xd2, 0xba, 0xbe, 0x89, 0x96, 0x95, 0xc2, 0xca, 0x99, 0x17, + 0xdb, 0x6d, 0xd0, 0xd7, 0x09, 0x05, 0x83, 0x51, 0x5a, 0x17, 0x2d, 0xff, + 0x5d, 0xcf, 0x37, 0x75, 0xa6, 0xfa, 0x82, 0x1d, 0xd6, 0x90, 0x1a, 0x8c, + 0x73, 0x28, 0x1f, 0x51, 0x81, 0x03, 0x52, 0xaa, 0x29, 0xd7, 0xac, 0x4e, + 0xec, 0x17, 0x0c, 0x38, 0x62, 0x82, 0x9d, 0xfa, 0xaa, 0x89, 0xe6, 0x59, + 0xb5, 0x8f, 0xd6, 0xbe, 0x83, 0xf5, 0x34, 0x61, 0x3d, 0x5f, 0x9c, 0x02, + 0xdb, 0x15, 0xa5, 0xac, 0x6b, 0xcb, 0xa1, 0xe5, 0x9a, 0x3a, 0x98, 0x6a, + 0x06, 0xf3, 0x16, 0x22, 0x67, 0xb9, 0x1a, 0x1e, 0xef, 0x30, 0x16, 0xcc, + 0xf2, 0xe6, 0x81, 0x03, 0xe9, 0xe1, 0x22, 0x57, 0x1f, 0x20, 0xcd, 0x2f, + 0x09, 0x70, 0x6c, 0x99, 0xbf, 0x8b, 0xd7, 0xe6, 0x8b, 0x24, 0xd1, 0xce, + 0x7b, 0xc9, 0x75, 0x45, 0xdd, 0x64, 0x62, 0x81, 0xac, 0x72, 0x58, 0xfc, + 0x4e, 0xd8, 0x17, 0xb0, 0x08, 0x43, 0x12, 0x89, 0xf0, 0x81, 0x46, 0xfb, + 0x7c, 0xb2, 0xd8, 0xd3, 0xcb, 0x57, 0x13, 0x8b, 0xc7, 0xee, 0x35, 0xf8, + 0xc9, 0x75, 0xfa, 0x6e, 0x95, 0x83, 0x0f, 0xac, 0xf0, 0x64, 0x79, 0x52, + 0xfc, 0x84, 0x3f, 0xe4, 0xd9, 0x17, 0xc8, 0xc2, 0xb4, 0x8d, 0x88, 0x75, + 0x91, 0xf0, 0xde, 0x4c, 0x42, 0x6c, 0x16, 0xff, 0x32, 0xff, 0x48, 0x67, + 0xa3, 0x23, 0x93, 0x58, 0x90, 0x73, 0x35, 0xc2, 0x1b, 0x0b, 0xa1, 0xa4, + 0x5b, 0x5a, 0xd8, 0x40, 0x62, 0x2f, 0x0e, 0x11, 0x17, 0x99, 0x3a, 0x2c, + 0xcb, 0x88, 0x73, 0x68, 0x04, 0xcf, 0x2e, 0x84, 0x77, 0x7d, 0x87, 0xd1, + 0x46, 0x62, 0xbb, 0x07, 0x49, 0xec, 0xd8, 0x00, 0x14, 0x1b, 0x24, 0xe0, + 0x4b, 0x6b, 0x4a, 0xab, 0x5a, 0x81, 0xb8, 0xb7, 0xce, 0x33, 0x38, 0x07, + 0xe4, 0x62, 0xdf, 0x82, 0xba, 0xf5, 0x9d, 0xc5, 0x73, 0xf6, 0xde, 0x47, + 0x62, 0xff, 0x1c, 0x24, 0x8e, 0x22, 0x9f, 0xc5, 0x5f, 0xbf, 0x92, 0x38, + 0x87, 0x10, 0xd6, 0x02, 0x74, 0x3f, 0xbf, 0x82, 0x4c, 0x1c, 0x92, 0x99, + 0x22, 0x75, 0x41, 0x09, 0x68, 0x78, 0x7b, 0x8d, 0xbd, 0x0a, 0x9e, 0x24, + 0xb1, 0xa2, 0x41, 0x1e, 0x4a, 0x20, 0xbf, 0xc6, 0x56, 0x05, 0xbb, 0x48, + 0x2c, 0x7f, 0xb0, 0x91, 0x2f, 0x03, 0x70, 0x2c, 0x41, 0xf9, 0x94, 0x88, + 0x87, 0x12, 0x8d, 0x7c, 0x09, 0xfa, 0x6c, 0xb0, 0x04, 0x12, 0xf1, 0xb5, + 0x09, 0x70, 0x34, 0xf2, 0x19, 0xe8, 0xd6, 0x62, 0xdc, 0xf2, 0xaf, 0x7d, + 0x3a, 0xf4, 0xd5, 0x8f, 0xfa, 0x44, 0xa2, 0x47, 0xdf, 0x5d, 0x5f, 0xc7, + 0x69, 0xd0, 0x77, 0x67, 0xe2, 0xa5, 0x28, 0x85, 0x1f, 0x56, 0x9e, 0x61, + 0xac, 0xbf, 0x44, 0x06, 0x8e, 0xed, 0xb9, 0xf1, 0x08, 0x78, 0x5c, 0xf8, + 0xc0, 0x75, 0x81, 0x45, 0xd0, 0x88, 0x3a, 0xc9, 0xe3, 0x3f, 0x98, 0x0d, + 0x5d, 0x8c, 0x67, 0x8b, 0x5a, 0x1c, 0x43, 0xdc, 0x0c, 0x2c, 0x14, 0x16, + 0xce, 0x6c, 0xe4, 0x1a, 0xd5, 0x8d, 0xa9, 0xac, 0x2b, 0x38, 0x9b, 0x81, + 0x2d, 0xcb, 0x8b, 0xcb, 0xa9, 0x3c, 0xe0, 0x02, 0x3b, 0x04, 0x22, 0x9b, + 0xfc, 0xc1, 0xd9, 0x16, 0x50, 0xc1, 0x97, 0xd1, 0xbe, 0x8e, 0xdf, 0x37, + 0xa4, 0x06, 0x74, 0x33, 0xd2, 0x50, 0xd6, 0x76, 0x0a, 0x63, 0x8e, 0x4f, + 0x43, 0xb5, 0x88, 0xc4, 0x4c, 0x43, 0x64, 0x2a, 0x89, 0x69, 0x87, 0x18, + 0x57, 0x23, 0x60, 0x88, 0x85, 0xba, 0x59, 0x0c, 0x1f, 0x19, 0xbc, 0xcf, + 0xdb, 0x88, 0xfe, 0x2e, 0xab, 0xcb, 0xaf, 0x50, 0x19, 0x60, 0x7f, 0x83, + 0x1a, 0xc6, 0x42, 0xf5, 0x0a, 0x5a, 0x3a, 0x71, 0xda, 0xe5, 0x1f, 0x73, + 0x85, 0x27, 0x9c, 0x6b, 0x5e, 0x12, 0x1c, 0xc7, 0xdd, 0xf0, 0x63, 0x61, + 0x9c, 0x04, 0x3b, 0xf7, 0xaf, 0x6e, 0xa8, 0x4c, 0xc4, 0xff, 0x90, 0x20, + 0x07, 0xb4, 0xb0, 0x7f, 0x35, 0x79, 0x32, 0x11, 0x7f, 0x3b, 0xe1, 0x86, + 0x1f, 0x0a, 0xd9, 0x72, 0xdd, 0x4a, 0xd2, 0xba, 0x5d, 0x30, 0x75, 0xef, + 0x5d, 0x99, 0xc9, 0xed, 0x14, 0x8c, 0xc7, 0x96, 0xd5, 0x9f, 0xab, 0xe7, + 0x60, 0xa4, 0x33, 0x0d, 0x18, 0xe7, 0x19, 0xf9, 0xc2, 0xf2, 0xbf, 0x70, + 0xa7, 0x4e, 0x8e, 0xe5, 0x97, 0x08, 0x5f, 0x44, 0x1d, 0x2b, 0x6e, 0x57, + 0x69, 0x4f, 0xca, 0x0c, 0x73, 0x82, 0xd8, 0xab, 0x05, 0xfb, 0x52, 0xa6, + 0xda, 0xe0, 0x71, 0xd4, 0x2f, 0xab, 0x8f, 0x62, 0xff, 0x26, 0x12, 0x83, + 0x89, 0x58, 0xc7, 0x8e, 0x23, 0xfa, 0x66, 0x26, 0xc0, 0x86, 0x53, 0x21, + 0x6b, 0x39, 0xdb, 0x6a, 0x7a, 0x46, 0xd7, 0xb4, 0x43, 0x60, 0x4f, 0x65, + 0x8a, 0xc7, 0x1a, 0x06, 0xb9, 0xb0, 0x60, 0x3f, 0x75, 0x87, 0xcd, 0x23, + 0x6c, 0xec, 0x65, 0xc5, 0xd2, 0x40, 0xe6, 0xee, 0xb0, 0xc0, 0xcb, 0x2b, + 0x03, 0x87, 0x02, 0x97, 0xb9, 0x5f, 0x0a, 0xb7, 0x1e, 0xfb, 0x99, 0x30, + 0xee, 0x78, 0xa6, 0xf8, 0x95, 0x75, 0x0f, 0x8e, 0xb0, 0x3c, 0xf8, 0x38, + 0x30, 0xcd, 0xba, 0x88, 0x2b, 0x87, 0x8c, 0x16, 0x12, 0xab, 0x1c, 0xca, + 0x10, 0x5f, 0x37, 0x8b, 0xe6, 0x8c, 0x70, 0xa6, 0x28, 0x5a, 0x33, 0xf1, + 0x17, 0x9c, 0x67, 0x65, 0x94, 0x69, 0xbd, 0x99, 0xe2, 0x45, 0xeb, 0x6e, + 0x4c, 0x9f, 0x03, 0x3a, 0x71, 0x2a, 0xe4, 0x05, 0xd6, 0x37, 0x98, 0x41, + 0x15, 0x26, 0xb1, 0xf5, 0x83, 0xeb, 0x03, 0x99, 0x11, 0x4d, 0x58, 0x2f, + 0xaa, 0x77, 0x86, 0x05, 0x47, 0x37, 0x94, 0xd8, 0xe4, 0x2c, 0x50, 0x45, + 0xc2, 0x42, 0xce, 0xf1, 0x0c, 0x45, 0xb6, 0xd5, 0x0d, 0xd6, 0x5b, 0x5c, + 0xa0, 0xde, 0xa9, 0x0a, 0x43, 0x78, 0x3a, 0x64, 0x88, 0x6c, 0xab, 0x66, + 0xcf, 0x91, 0xd9, 0x50, 0x5c, 0x26, 0xab, 0x22, 0x19, 0xe2, 0xae, 0xca, + 0xfa, 0x59, 0x19, 0x61, 0xb5, 0xf8, 0x3a, 0x97, 0x63, 0xcd, 0x14, 0xad, + 0xe6, 0xb7, 0xa3, 0x99, 0xbb, 0xff, 0x14, 0x65, 0x45, 0xa7, 0x5f, 0x2d, + 0x0e, 0x5a, 0xb4, 0xe1, 0x15, 0x7e, 0xbd, 0x78, 0x57, 0x9e, 0x4a, 0xbc, + 0xc8, 0x5d, 0x34, 0x9b, 0x95, 0xf2, 0xa6, 0x0f, 0x5e, 0x69, 0x58, 0x6a, + 0x49, 0xc2, 0xa2, 0x16, 0x4f, 0x59, 0x5f, 0x5a, 0xbe, 0x94, 0x4b, 0xfa, + 0x0e, 0xfb, 0x61, 0x97, 0x0b, 0xdb, 0xa3, 0x8d, 0x60, 0x1d, 0xbb, 0x51, + 0x96, 0x17, 0xef, 0x91, 0x52, 0x90, 0xcb, 0xc5, 0x3a, 0x54, 0x81, 0x1f, + 0x1d, 0xd1, 0x84, 0xb7, 0x04, 0xb6, 0xa9, 0x59, 0xf8, 0x49, 0xaa, 0x3a, + 0xfc, 0x2a, 0xa6, 0x57, 0x3f, 0x05, 0x85, 0x59, 0x01, 0x6d, 0x78, 0x41, + 0x40, 0x17, 0xae, 0x0f, 0xe8, 0x11, 0x86, 0x43, 0x82, 0xa6, 0xbb, 0x2d, + 0x00, 0xb6, 0x57, 0x05, 0xbb, 0xf4, 0xaa, 0xe0, 0x99, 0x99, 0xdb, 0xab, + 0x16, 0x17, 0x5b, 0xc7, 0x82, 0xae, 0x14, 0x4e, 0xe9, 0x8a, 0x34, 0xad, + 0x86, 0x43, 0x28, 0x71, 0xc3, 0x3a, 0x91, 0x79, 0x72, 0x89, 0x19, 0xc2, + 0x01, 0x97, 0x56, 0x4c, 0xc4, 0x2b, 0x90, 0x9f, 0x1a, 0x64, 0xbd, 0x58, + 0x0e, 0x8b, 0xcc, 0x86, 0xfd, 0x24, 0xf6, 0x82, 0xc2, 0x07, 0x29, 0xcf, + 0x26, 0xae, 0x54, 0xac, 0xfb, 0x05, 0xf3, 0xb1, 0xa8, 0xa9, 0xa3, 0xb7, + 0x40, 0x15, 0xb8, 0x08, 0xd6, 0x54, 0xe4, 0xc4, 0x36, 0x5e, 0x48, 0x95, + 0xee, 0x08, 0xa4, 0x04, 0x88, 0x6b, 0xb7, 0xa0, 0x93, 0x9a, 0x03, 0xd5, + 0x81, 0xed, 0x02, 0x2b, 0x3d, 0x2e, 0x30, 0x92, 0x68, 0xa1, 0x54, 0x6c, + 0x42, 0x78, 0x9f, 0x3a, 0x32, 0x16, 0x52, 0xc3, 0x59, 0x81, 0xcd, 0xab, + 0xb5, 0x90, 0xb9, 0xdc, 0x08, 0x61, 0x81, 0x39, 0x7e, 0x07, 0xd2, 0xc5, + 0x5b, 0xbd, 0x6b, 0x31, 0x75, 0xff, 0x29, 0x82, 0x63, 0x8c, 0x2d, 0x0c, + 0x94, 0x69, 0x77, 0x9a, 0x0e, 0x98, 0x9a, 0x33, 0x9a, 0xc9, 0x4e, 0x68, + 0x26, 0x28, 0xc3, 0xb4, 0x2d, 0xcc, 0x13, 0x89, 0xf8, 0x3f, 0x47, 0x54, + 0x79, 0x6c, 0x13, 0x91, 0xee, 0x70, 0x9b, 0x64, 0xe6, 0x09, 0x28, 0xcc, + 0x38, 0x84, 0xd2, 0xff, 0x89, 0xf5, 0x01, 0xd6, 0x31, 0x0d, 0x53, 0x24, + 0xe2, 0xe7, 0x46, 0x54, 0xc0, 0x36, 0xed, 0xc7, 0x5a, 0xef, 0x70, 0xeb, + 0x24, 0xb6, 0x65, 0x1c, 0xc2, 0x99, 0x21, 0x9a, 0x50, 0x7e, 0x9f, 0x1d, + 0xf7, 0xa9, 0xe5, 0xd3, 0xf4, 0x43, 0x10, 0x59, 0xe4, 0xf0, 0x13, 0xc7, + 0x9d, 0x9e, 0x83, 0xd0, 0xbc, 0xc8, 0xf0, 0x44, 0x9d, 0xdf, 0x74, 0x50, + 0x5c, 0xd8, 0xe6, 0x47, 0xa9, 0xe4, 0x67, 0xdc, 0xc6, 0xb0, 0xaa, 0x82, + 0x0d, 0xbf, 0xe3, 0xcb, 0x3c, 0xa8, 0x7a, 0x4f, 0xf5, 0xa6, 0x1d, 0x88, + 0x8d, 0x75, 0xe8, 0xca, 0x3c, 0x02, 0xc4, 0x7e, 0x39, 0x0c, 0x7c, 0x4a, + 0x58, 0x17, 0x26, 0x15, 0xfa, 0x30, 0xf0, 0xec, 0x9e, 0xb4, 0x26, 0x75, + 0x58, 0x8f, 0xf5, 0x4d, 0x1c, 0x51, 0x8b, 0xbf, 0x59, 0x6d, 0xe5, 0xd4, + 0x61, 0x96, 0x67, 0xc2, 0xe9, 0x08, 0x8d, 0x5a, 0x9c, 0x86, 0x32, 0xe9, + 0x58, 0x03, 0x1f, 0xa0, 0xf0, 0xb4, 0x8e, 0xa8, 0xf3, 0x34, 0x92, 0x13, + 0xee, 0x70, 0x83, 0x74, 0xd3, 0x39, 0xe0, 0xdb, 0x1e, 0xc8, 0xef, 0x65, + 0x1d, 0x69, 0x2d, 0xe9, 0x07, 0x20, 0xf6, 0xa3, 0xe1, 0x74, 0x51, 0x1f, + 0xb1, 0xfe, 0x66, 0xb1, 0x27, 0xad, 0x49, 0xd3, 0x9c, 0xde, 0x3c, 0xeb, + 0xa4, 0x5e, 0xec, 0x75, 0xe4, 0xa5, 0xee, 0xe5, 0x8f, 0x41, 0x0f, 0x8c, + 0xf5, 0xec, 0x11, 0x34, 0xf2, 0xab, 0xab, 0x7b, 0x03, 0xad, 0xc8, 0x03, + 0x27, 0x0e, 0xcc, 0x15, 0xe6, 0xce, 0x24, 0xb6, 0x62, 0xcf, 0xde, 0x07, + 0x2e, 0x04, 0x50, 0xa1, 0x93, 0x0b, 0xcf, 0x4d, 0x05, 0x3b, 0xdc, 0xe8, + 0x4a, 0xc4, 0x6f, 0xc2, 0x7e, 0x4a, 0x95, 0x06, 0x57, 0xb0, 0x11, 0xab, + 0x2a, 0x53, 0x25, 0xa6, 0x36, 0xa7, 0x46, 0x04, 0x90, 0x74, 0xe7, 0x1a, + 0x79, 0x0c, 0xd1, 0x58, 0xbc, 0x6c, 0x73, 0x2e, 0xd2, 0x3a, 0x62, 0x43, + 0xdc, 0xb7, 0xdd, 0x8a, 0xf1, 0x61, 0xa4, 0x90, 0x2c, 0xc8, 0x8d, 0x64, + 0x35, 0xb2, 0x18, 0x0e, 0x3d, 0x2b, 0xa2, 0x9c, 0xaa, 0x6d, 0x7b, 0x63, + 0xea, 0x16, 0x0c, 0x37, 0x20, 0x8c, 0x6c, 0xb8, 0x2e, 0xaa, 0x41, 0xd8, + 0x5f, 0x1f, 0x7e, 0x75, 0xf5, 0xe9, 0x06, 0xb5, 0xd8, 0xc5, 0x35, 0x09, + 0xcf, 0x76, 0xf7, 0xda, 0x34, 0x62, 0x17, 0xf6, 0xf3, 0x5e, 0xbb, 0xca, + 0xc3, 0xda, 0x8e, 0x82, 0x1e, 0xc7, 0xe4, 0xcd, 0x72, 0xb6, 0xd2, 0x62, + 0xa6, 0xc9, 0xca, 0x51, 0x39, 0x9c, 0x6c, 0x73, 0x3e, 0xb6, 0xf9, 0x31, + 0x39, 0x5b, 0x4c, 0xc3, 0x91, 0xf2, 0x98, 0x9c, 0x2e, 0x6a, 0x22, 0xd6, + 0xd4, 0x1e, 0xed, 0x62, 0x8f, 0xa6, 0x39, 0xed, 0x00, 0xeb, 0xe8, 0x5b, + 0x0e, 0x31, 0xd3, 0x70, 0x5f, 0x5d, 0x3a, 0xa6, 0xfc, 0xf1, 0x30, 0x2d, + 0x5d, 0x23, 0xf6, 0xfa, 0xf9, 0x5a, 0x9d, 0xd8, 0xb6, 0x39, 0x53, 0x6c, + 0xab, 0xcd, 0x12, 0x2f, 0xd4, 0xa6, 0x88, 0x17, 0x1e, 0x20, 0x48, 0x13, + 0x69, 0x61, 0x37, 0x68, 0x22, 0xec, 0x93, 0xfa, 0xe6, 0x3c, 0x98, 0x1d, + 0x25, 0x88, 0xb7, 0x6c, 0xc4, 0xdb, 0x3f, 0x87, 0xf4, 0x62, 0x5a, 0x13, + 0x71, 0xeb, 0xc3, 0xb4, 0x8c, 0x95, 0xc3, 0x7a, 0x94, 0x38, 0x68, 0x61, + 0x9e, 0x22, 0x76, 0x66, 0x67, 0xf6, 0x01, 0x75, 0x0b, 0xd9, 0xa9, 0x6f, + 0xfd, 0xcd, 0x6a, 0x3d, 0x07, 0x3b, 0x8f, 0x35, 0x24, 0xa9, 0xe2, 0x2f, + 0xc3, 0xea, 0xbc, 0x0f, 0x24, 0x15, 0xf6, 0xc2, 0xc3, 0x32, 0xed, 0x83, + 0x5e, 0x7b, 0xaf, 0x2d, 0x5d, 0x3c, 0x0a, 0x96, 0xd4, 0x2e, 0xc8, 0xf0, + 0x30, 0x42, 0xbe, 0xac, 0x8b, 0x50, 0xcc, 0x44, 0x04, 0xd2, 0x4d, 0xdc, + 0xba, 0x70, 0x7a, 0x6b, 0x0e, 0x7a, 0x7c, 0x1e, 0x8b, 0x47, 0x8f, 0xc8, + 0xb4, 0x08, 0xd5, 0x32, 0x1f, 0xc8, 0x6f, 0xc9, 0xc6, 0x96, 0x66, 0x1f, + 0x64, 0xdd, 0x63, 0xc2, 0x79, 0x62, 0xcb, 0x6c, 0x75, 0xde, 0xf4, 0xd3, + 0xb4, 0xc4, 0xf9, 0x38, 0x42, 0xb2, 0xa2, 0x8d, 0xb6, 0x2e, 0xd8, 0x24, + 0x98, 0x65, 0x5d, 0xeb, 0xfc, 0xf6, 0x6d, 0xdc, 0xb6, 0xf6, 0x29, 0x55, + 0xba, 0x9d, 0x53, 0xaa, 0x5d, 0x1e, 0xe2, 0xdd, 0x21, 0xa8, 0xe4, 0x46, + 0xde, 0xaa, 0xc9, 0xf3, 0x1e, 0x8f, 0xae, 0xcd, 0x91, 0x25, 0xab, 0xaa, + 0x0c, 0x6b, 0xda, 0x96, 0xba, 0x43, 0x78, 0xaf, 0xbb, 0x99, 0x79, 0xd2, + 0xfc, 0x6e, 0xb4, 0x8b, 0xef, 0x81, 0x56, 0xe1, 0x6d, 0xd4, 0xb7, 0x2d, + 0x1e, 0xad, 0x9b, 0x09, 0x67, 0x2a, 0x38, 0x4d, 0x69, 0x66, 0xdd, 0xbf, + 0x59, 0x9d, 0xc4, 0xea, 0xb1, 0x06, 0xda, 0x8a, 0xf5, 0xc3, 0x77, 0xb8, + 0x7e, 0x21, 0x9f, 0xb9, 0x9c, 0xde, 0x8a, 0x7a, 0x8e, 0x9c, 0x06, 0x6e, + 0x60, 0xf7, 0xac, 0x89, 0xba, 0x21, 0xa7, 0xc6, 0xe7, 0xc9, 0x12, 0x52, + 0x24, 0xa6, 0xf8, 0x4b, 0xb9, 0x5c, 0x95, 0xa2, 0x6a, 0x4e, 0xa5, 0x2d, + 0xf9, 0xc7, 0xf1, 0xc6, 0xa2, 0xeb, 0x35, 0x69, 0xde, 0x8f, 0xa3, 0xa4, + 0xe8, 0x41, 0xe1, 0xc3, 0x28, 0xfb, 0xc4, 0x43, 0x97, 0xd9, 0x56, 0x52, + 0x06, 0x72, 0xfc, 0x32, 0xd2, 0x47, 0xf7, 0x17, 0x97, 0xd3, 0x6b, 0x58, + 0x85, 0x47, 0xb1, 0xe1, 0xcf, 0x2e, 0xf3, 0x81, 0xba, 0x40, 0xbd, 0xdf, + 0x20, 0x3a, 0xfc, 0x22, 0x24, 0x47, 0x84, 0x51, 0x24, 0x48, 0x65, 0x65, + 0x97, 0x09, 0x6f, 0x0c, 0x3f, 0x70, 0x99, 0xe1, 0x27, 0x5e, 0xfe, 0x82, + 0xea, 0xbb, 0x43, 0xe9, 0x28, 0xb4, 0x62, 0xb7, 0xc1, 0x50, 0x62, 0x23, + 0x3e, 0xc8, 0xab, 0x73, 0xe0, 0x3d, 0x85, 0x03, 0xa5, 0x34, 0x68, 0x90, + 0x1a, 0x53, 0xc2, 0xe9, 0xa0, 0x6f, 0x4e, 0xc4, 0xaf, 0x0c, 0xeb, 0x45, + 0x8a, 0x51, 0x1d, 0x8e, 0x16, 0x75, 0xb8, 0x45, 0x30, 0x49, 0x3a, 0xa4, + 0xb5, 0x54, 0xe9, 0xca, 0x0a, 0x8b, 0x8a, 0x57, 0x20, 0x0c, 0x0b, 0xe2, + 0xcc, 0x46, 0xc7, 0x31, 0xc8, 0xf2, 0x4c, 0xad, 0xa1, 0x50, 0xa8, 0xc3, + 0x29, 0x4f, 0x17, 0xa3, 0x64, 0x7d, 0x74, 0x48, 0x13, 0x51, 0xe5, 0x86, + 0x85, 0xf2, 0x6e, 0x8d, 0x58, 0x06, 0x56, 0x8b, 0x06, 0x69, 0x20, 0xe0, + 0xd6, 0x2a, 0xe3, 0x2b, 0x05, 0x31, 0xa3, 0x11, 0x59, 0x07, 0x84, 0xb5, + 0x2d, 0x15, 0x81, 0x44, 0xfc, 0xa3, 0x21, 0x92, 0x67, 0x93, 0x53, 0x44, + 0xeb, 0x6f, 0x56, 0x78, 0x96, 0xa0, 0x75, 0x82, 0x23, 0x14, 0x6b, 0xc9, + 0x97, 0x7a, 0xed, 0x8d, 0x0e, 0x67, 0xea, 0x51, 0x38, 0x06, 0x66, 0xcf, + 0x4e, 0x61, 0x9c, 0xac, 0x8e, 0x3c, 0x6b, 0xd1, 0xa9, 0x4a, 0x55, 0x8d, + 0x38, 0x36, 0x9a, 0x84, 0xf4, 0xe3, 0xb9, 0x35, 0x19, 0x1e, 0x7c, 0xbc, + 0x07, 0x04, 0x56, 0x66, 0x50, 0x06, 0xe9, 0x80, 0xf2, 0x33, 0x75, 0x64, + 0x49, 0xbb, 0xc8, 0x88, 0x38, 0x96, 0xd5, 0x38, 0x2e, 0x2f, 0x58, 0x56, + 0x78, 0x2c, 0xc2, 0xcb, 0xf2, 0x61, 0x75, 0x1b, 0x4a, 0xe1, 0x8f, 0xa5, + 0x6c, 0xf1, 0xb9, 0xd4, 0x24, 0x2f, 0xce, 0x42, 0x8a, 0x26, 0x28, 0x3f, + 0xca, 0x80, 0x75, 0x8b, 0x48, 0xf7, 0x0e, 0xa8, 0x40, 0xba, 0x67, 0x76, + 0x25, 0xe2, 0xfb, 0x10, 0x9e, 0x6e, 0xa4, 0x7c, 0x8b, 0x35, 0x4b, 0xe4, + 0xcc, 0x24, 0xa6, 0xe9, 0x57, 0x8b, 0x8b, 0xcc, 0xef, 0x53, 0xbd, 0x05, + 0x71, 0x95, 0xc4, 0x9d, 0xc9, 0x93, 0xdf, 0xb1, 0x5b, 0xfd, 0x5c, 0x2a, + 0xb3, 0x4b, 0xb3, 0x9b, 0xec, 0x82, 0x02, 0xd8, 0x45, 0x75, 0x04, 0xf6, + 0x08, 0xe5, 0x8d, 0x3b, 0x8f, 0x18, 0x90, 0x33, 0x6a, 0x40, 0x13, 0x36, + 0xa0, 0xcc, 0x49, 0x69, 0xa6, 0x56, 0xa1, 0xcf, 0x67, 0xc0, 0x91, 0x5a, + 0xbe, 0x5c, 0x2d, 0x56, 0xcf, 0x89, 0xd4, 0xae, 0x5b, 0x7e, 0xba, 0xb6, + 0x6a, 0xae, 0xa6, 0xa5, 0x04, 0xa5, 0xc5, 0xce, 0x7e, 0x0d, 0xda, 0x2d, + 0xf9, 0x1c, 0xd5, 0xba, 0xd7, 0xf6, 0x6b, 0x9b, 0x48, 0xb1, 0x46, 0xae, + 0x08, 0x4d, 0x72, 0xa6, 0xca, 0x5a, 0x71, 0x90, 0xd3, 0x84, 0x3f, 0x8a, + 0x6a, 0x45, 0xc6, 0xa9, 0x91, 0x19, 0xc7, 0x54, 0xb8, 0xb1, 0x9a, 0xc4, + 0xfe, 0x84, 0xf6, 0xd7, 0x3f, 0x25, 0x1a, 0x97, 0x8b, 0x35, 0x10, 0x5e, + 0x17, 0x2e, 0x86, 0x29, 0x18, 0xbe, 0xaa, 0x7f, 0x22, 0x57, 0x0c, 0x6e, + 0x74, 0xdd, 0xda, 0xaf, 0x6f, 0xa2, 0xd6, 0x11, 0x53, 0x9c, 0x8a, 0xb9, + 0x8a, 0xe1, 0x3a, 0x0c, 0x6b, 0xc7, 0x5c, 0x1a, 0x59, 0x27, 0x92, 0x0a, + 0xec, 0x4b, 0xb4, 0xb2, 0x0e, 0xe5, 0xc8, 0x51, 0xf4, 0xe1, 0x28, 0xd1, + 0x8b, 0x9f, 0x72, 0x67, 0xa3, 0x15, 0x68, 0xc5, 0xde, 0x24, 0xa5, 0x88, + 0xf9, 0x7e, 0x3e, 0x95, 0x71, 0x56, 0xc8, 0xf9, 0xbe, 0x02, 0x15, 0xc5, + 0x54, 0xa1, 0x1c, 0x2b, 0xfc, 0x54, 0x7d, 0x9d, 0x9d, 0x42, 0xf7, 0xab, + 0x3e, 0x41, 0x98, 0x37, 0x33, 0xf5, 0xa0, 0xaa, 0xd9, 0x5a, 0x63, 0x10, + 0xb5, 0xad, 0x1e, 0x81, 0x69, 0x56, 0x47, 0x54, 0x9e, 0xf4, 0x9d, 0xc8, + 0xbd, 0x77, 0x3a, 0x51, 0xb3, 0x56, 0xb7, 0x72, 0xe5, 0xa9, 0x4f, 0xa6, + 0x3d, 0x95, 0x88, 0x7f, 0x36, 0xc4, 0xe6, 0x8d, 0xe9, 0x81, 0xe2, 0x1d, + 0xb2, 0x5a, 0xec, 0xf9, 0x1e, 0x95, 0xd1, 0xcc, 0x8d, 0xa9, 0xbd, 0x69, + 0xbe, 0xe7, 0x98, 0x1c, 0xaf, 0x5a, 0x74, 0x01, 0xe7, 0x86, 0xb0, 0xb1, + 0x86, 0xc7, 0x1c, 0x89, 0xf8, 0xe2, 0x04, 0x9b, 0xf7, 0xde, 0x69, 0x1b, + 0x64, 0x60, 0xef, 0x65, 0x17, 0x2c, 0x15, 0xfa, 0xa3, 0x09, 0x15, 0xa2, + 0x78, 0xe8, 0x3a, 0xb8, 0x84, 0xb4, 0x8a, 0x0a, 0xb5, 0xed, 0x4e, 0x3d, + 0xd8, 0x74, 0xa0, 0xd0, 0x6d, 0x30, 0xd6, 0xc1, 0xc2, 0xa6, 0x65, 0xba, + 0x15, 0xad, 0x47, 0x7a, 0xfd, 0x38, 0x82, 0x24, 0x1f, 0xd5, 0x73, 0xe4, + 0x0b, 0xb5, 0x46, 0xd4, 0x26, 0xfe, 0xd4, 0x4b, 0x0a, 0xb7, 0x2f, 0xbf, + 0x50, 0x9b, 0xb0, 0x93, 0x98, 0xb3, 0xaf, 0x6d, 0xf5, 0x2a, 0x21, 0xb2, + 0x3c, 0x61, 0xef, 0x6d, 0x28, 0x44, 0x2b, 0x80, 0x47, 0x7f, 0x61, 0x6d, + 0x64, 0x05, 0x94, 0x12, 0xb9, 0x6e, 0x59, 0x34, 0x5a, 0xb7, 0xec, 0x34, + 0xba, 0x6b, 0xa4, 0xf3, 0xcb, 0x2c, 0x2b, 0xa1, 0xb4, 0x4a, 0x5a, 0xb2, + 0xd2, 0x71, 0x1f, 0x38, 0x2b, 0xa5, 0xfa, 0xfb, 0x28, 0xcf, 0xe2, 0xeb, + 0xea, 0xeb, 0x78, 0x80, 0xc2, 0x22, 0xb8, 0xd1, 0xcd, 0x81, 0xd1, 0x51, + 0x02, 0xcf, 0xd7, 0x5d, 0xaa, 0x73, 0x5d, 0xcf, 0x86, 0x21, 0x36, 0x92, + 0xa0, 0x7e, 0x6a, 0xab, 0xf4, 0x27, 0x6c, 0x4a, 0x5c, 0x15, 0x5a, 0xb5, + 0x57, 0x12, 0x39, 0xe8, 0x32, 0xed, 0x87, 0xd8, 0x67, 0x09, 0xc2, 0x8f, + 0x0b, 0x8f, 0x45, 0xec, 0x32, 0xd2, 0x38, 0xfc, 0xcd, 0x93, 0xf9, 0xe5, + 0xc4, 0x3d, 0x4f, 0xaa, 0xc7, 0xdf, 0xb9, 0x92, 0x63, 0xc5, 0xf1, 0x74, + 0x91, 0xe3, 0xeb, 0x59, 0x51, 0xfb, 0x67, 0xed, 0x5b, 0x6d, 0xab, 0x7b, + 0x97, 0xe7, 0x2e, 0x47, 0x8d, 0x34, 0x96, 0x9f, 0x00, 0x5b, 0xed, 0xbd, + 0x7b, 0xef, 0xed, 0xbd, 0xb7, 0x70, 0x59, 0x43, 0x6f, 0xc2, 0xd1, 0x1e, + 0xbd, 0xb1, 0xe6, 0xe5, 0xe8, 0x8d, 0xbe, 0x57, 0xa2, 0x6d, 0xab, 0xad, + 0xcb, 0x97, 0xe8, 0xd0, 0x12, 0xee, 0x5e, 0xd9, 0xab, 0x3d, 0xa4, 0x0a, + 0x4f, 0xf5, 0x4d, 0xad, 0x61, 0x70, 0x44, 0xea, 0x9a, 0x75, 0x0e, 0x12, + 0xbe, 0xde, 0xa7, 0x6f, 0x86, 0xb0, 0x0d, 0xa6, 0xf8, 0xc6, 0x1e, 0x34, + 0x1d, 0x20, 0x53, 0xb4, 0x48, 0x89, 0xd7, 0x0d, 0x41, 0xf1, 0xec, 0x9e, + 0x69, 0x12, 0x6a, 0x9b, 0x63, 0xbc, 0x39, 0x53, 0x24, 0x93, 0x68, 0x78, + 0x91, 0xaf, 0xcb, 0x10, 0x6d, 0xa0, 0x0e, 0xd7, 0xd7, 0x39, 0x6b, 0x9c, + 0x3e, 0x78, 0xca, 0x74, 0x20, 0x11, 0x7f, 0x7a, 0x04, 0x8a, 0xdd, 0x3d, + 0x06, 0x31, 0xd2, 0x6e, 0x35, 0x32, 0x4e, 0x22, 0x8d, 0xb5, 0xdd, 0x15, + 0x85, 0xd2, 0x41, 0x79, 0x30, 0x40, 0x75, 0xc7, 0xf3, 0xab, 0xc3, 0xc2, + 0x97, 0xdd, 0x17, 0x96, 0x55, 0x34, 0x50, 0x9f, 0x63, 0x4d, 0x58, 0xf8, + 0xac, 0x9b, 0xbf, 0xef, 0x61, 0xc5, 0x57, 0x87, 0xbe, 0x68, 0x77, 0xfd, + 0x7d, 0x6d, 0xab, 0x7f, 0x13, 0x30, 0x2f, 0xdf, 0x2e, 0x9c, 0x93, 0xbf, + 0x1b, 0xe8, 0x69, 0x88, 0x08, 0x67, 0x65, 0xc3, 0x21, 0x0a, 0x4d, 0xb6, + 0x2f, 0xbb, 0x86, 0xd6, 0xb0, 0x12, 0x6b, 0x60, 0x4f, 0x6f, 0xc9, 0x01, + 0xf9, 0xc1, 0xa8, 0x19, 0xfb, 0x97, 0x5f, 0x61, 0x88, 0x2c, 0xf0, 0xf0, + 0xf5, 0x29, 0x91, 0xfa, 0x15, 0x0b, 0x3c, 0xf5, 0xf5, 0xc6, 0x48, 0x1b, + 0xbe, 0xdb, 0xea, 0xef, 0x8b, 0xde, 0x61, 0xcb, 0x8b, 0x26, 0x12, 0x89, + 0x8d, 0x28, 0xfa, 0x81, 0xf6, 0xf7, 0x47, 0x3c, 0xed, 0xf3, 0x58, 0x3a, + 0xe5, 0x51, 0x1c, 0x9a, 0xe7, 0x46, 0x88, 0x6d, 0x44, 0x34, 0x6d, 0x8c, + 0x75, 0xa4, 0x43, 0x0a, 0xda, 0x9f, 0xdb, 0x8e, 0x68, 0x9b, 0xd3, 0x22, + 0xba, 0x1b, 0x0c, 0xf7, 0xfa, 0xea, 0xdf, 0xab, 0x7f, 0x6f, 0xa9, 0x11, + 0x52, 0x72, 0xb5, 0x07, 0xa7, 0x81, 0x06, 0xb9, 0xcf, 0x4d, 0x28, 0xbb, + 0x74, 0x58, 0x6b, 0xad, 0x5c, 0xe3, 0xdb, 0xb7, 0x35, 0x22, 0x30, 0x32, + 0x53, 0xb8, 0x4a, 0x58, 0xdc, 0x4b, 0xf8, 0xb6, 0xb5, 0x2f, 0x2d, 0xe7, + 0xfd, 0x2f, 0xd7, 0x1d, 0xca, 0xf9, 0x52, 0x5a, 0x05, 0xab, 0x52, 0xc9, + 0x44, 0x90, 0x1e, 0xe9, 0xdd, 0xb7, 0x75, 0xa6, 0xaf, 0x99, 0xc9, 0xf2, + 0x3a, 0x00, 0x75, 0xf2, 0x66, 0x6a, 0x23, 0xde, 0x5c, 0x93, 0x88, 0xa7, + 0x8d, 0xd0, 0x19, 0x07, 0x38, 0xbd, 0xba, 0x17, 0xb9, 0xdf, 0x13, 0x6c, + 0x98, 0x5f, 0xc5, 0x46, 0x5a, 0x51, 0xbb, 0xc9, 0x3e, 0xce, 0x05, 0x7a, + 0x97, 0x42, 0xf1, 0x0d, 0xd2, 0x4b, 0xab, 0x13, 0xf6, 0x08, 0x4a, 0xc2, + 0x2f, 0x47, 0x14, 0x9a, 0x59, 0x5a, 0x56, 0xa3, 0x12, 0xad, 0xc8, 0x13, + 0x27, 0x48, 0xd4, 0x7e, 0xd5, 0x63, 0x7b, 0x1d, 0x2b, 0xd4, 0xad, 0x06, + 0x94, 0x1d, 0x2c, 0xd2, 0x01, 0x1b, 0x3e, 0x1b, 0x35, 0x3a, 0xba, 0x6c, + 0x6c, 0xeb, 0x92, 0x40, 0x8d, 0x37, 0xc2, 0xb5, 0x6d, 0xdd, 0x19, 0x10, + 0x99, 0x14, 0x6f, 0x46, 0xa8, 0x11, 0xe6, 0x07, 0xf4, 0x9c, 0x5e, 0x9d, + 0xe2, 0x4d, 0xd6, 0x6e, 0xc3, 0xda, 0xdf, 0x47, 0x69, 0x77, 0x01, 0xdb, + 0x70, 0x4e, 0xb2, 0x63, 0x48, 0x22, 0x7e, 0xb9, 0xff, 0x64, 0xd4, 0x58, + 0x28, 0x46, 0x55, 0xa2, 0x7d, 0x45, 0x8b, 0x1a, 0x2d, 0x76, 0x55, 0x8a, + 0x97, 0x47, 0x3c, 0x30, 0x8e, 0xfa, 0xa5, 0x2f, 0xad, 0x9e, 0x2f, 0x88, + 0xcb, 0x1b, 0x53, 0xf7, 0xd5, 0xf5, 0xd6, 0x39, 0x96, 0xb6, 0x2d, 0x7d, + 0x5d, 0xda, 0xb7, 0xd5, 0x54, 0xdd, 0xcc, 0xec, 0x40, 0x4e, 0x97, 0x02, + 0x59, 0xde, 0x46, 0x47, 0xb3, 0x3a, 0xcb, 0x7b, 0x7e, 0x25, 0xea, 0x34, + 0xcd, 0x2e, 0xd0, 0x62, 0xe9, 0x7b, 0xb1, 0xf4, 0xc3, 0xa7, 0xe5, 0xe8, + 0x98, 0xc2, 0x75, 0x51, 0xd5, 0xd3, 0x7f, 0xa2, 0x3a, 0x3b, 0xe2, 0xfd, + 0xea, 0x18, 0x23, 0x0c, 0x1d, 0x7f, 0xc9, 0xbe, 0x30, 0x75, 0x24, 0xe2, + 0xfb, 0xfb, 0xe9, 0x8c, 0x04, 0x62, 0x1f, 0xf5, 0x3e, 0x23, 0x18, 0x9a, + 0x6b, 0x56, 0x1c, 0x5d, 0xae, 0xc5, 0xb4, 0xdb, 0x05, 0x38, 0x7e, 0xb1, + 0x77, 0xbb, 0x45, 0xd7, 0x8c, 0xb2, 0xe8, 0x94, 0x0e, 0xf9, 0xb6, 0x06, + 0x39, 0x3b, 0x38, 0x89, 0xac, 0x6b, 0xe9, 0xee, 0x6d, 0x74, 0xf0, 0x2b, + 0x8e, 0x31, 0xbf, 0x5a, 0x9d, 0x25, 0x20, 0x2d, 0xad, 0x78, 0xa3, 0x61, + 0xbb, 0x90, 0x25, 0x37, 0xda, 0xab, 0x55, 0x75, 0x2b, 0x52, 0x84, 0x0d, + 0xf2, 0xb3, 0xcb, 0x2f, 0x2c, 0xcf, 0xda, 0x99, 0x8d, 0xdc, 0xb1, 0x42, + 0x26, 0x8e, 0xf9, 0xc2, 0xbe, 0xfa, 0x0b, 0xf5, 0x8d, 0xbc, 0x63, 0x45, + 0x0f, 0xf6, 0x03, 0x5f, 0xff, 0xea, 0xea, 0xcb, 0x2b, 0x7a, 0x1a, 0x34, + 0x11, 0x7d, 0x58, 0xb4, 0xaa, 0xc3, 0x54, 0xd7, 0x51, 0x37, 0xd3, 0xf2, + 0xe6, 0xab, 0xb2, 0x04, 0x90, 0x0f, 0xf7, 0xf2, 0xa0, 0x73, 0x9b, 0xc2, + 0x6d, 0x5b, 0xef, 0xa9, 0x11, 0x19, 0x0b, 0x72, 0x94, 0x8c, 0x66, 0x7d, + 0xe4, 0x0a, 0x87, 0x50, 0x1c, 0x7b, 0xb1, 0xd7, 0x20, 0xa6, 0x20, 0xef, + 0xd7, 0x86, 0xb5, 0x08, 0x49, 0x0d, 0x4a, 0x8d, 0xfa, 0x15, 0xbb, 0x2a, + 0x45, 0xae, 0xbe, 0xfe, 0xc2, 0x0a, 0x91, 0xbb, 0x50, 0x6f, 0x10, 0xeb, + 0x67, 0x19, 0x10, 0x4a, 0xd1, 0xb2, 0x3f, 0xea, 0x00, 0x52, 0xe1, 0x29, + 0x1f, 0x73, 0x40, 0xdf, 0x3c, 0x26, 0x9c, 0x88, 0x0b, 0xfd, 0xd9, 0x07, + 0x34, 0xf0, 0xab, 0xd5, 0x48, 0x3f, 0xfd, 0xea, 0xa6, 0x2c, 0x2c, 0x41, + 0x2d, 0xbe, 0x24, 0xa8, 0x8e, 0x6b, 0xc5, 0xb6, 0xfa, 0x6c, 0xf1, 0xc5, + 0xa8, 0x5a, 0x8c, 0x59, 0x20, 0x36, 0x6d, 0x58, 0xad, 0x8c, 0xfd, 0x8a, + 0x61, 0x1b, 0x7f, 0xb7, 0x95, 0xdc, 0xf4, 0x18, 0x85, 0x0d, 0x58, 0x7e, + 0x2a, 0x30, 0xe1, 0x2c, 0x94, 0x6c, 0x87, 0x50, 0x6f, 0x64, 0x1d, 0x5a, + 0x51, 0xdf, 0x1a, 0x40, 0xad, 0xee, 0x91, 0x7e, 0x28, 0x5e, 0x20, 0x53, + 0x5b, 0xf9, 0x2b, 0xcb, 0xc9, 0x28, 0x83, 0x54, 0xd2, 0x56, 0x7f, 0xbe, + 0x7e, 0x7b, 0xf4, 0xc2, 0xca, 0xf4, 0x30, 0xbf, 0x92, 0x71, 0x9b, 0xe5, + 0xda, 0x95, 0x6d, 0x2b, 0xff, 0xc4, 0xfd, 0x5c, 0xc8, 0x3e, 0xf6, 0x63, + 0x21, 0x13, 0xeb, 0x7a, 0xc1, 0xfa, 0x34, 0x96, 0x98, 0x0b, 0xe9, 0xe2, + 0x5a, 0xcb, 0x22, 0xae, 0x14, 0x52, 0x5a, 0x20, 0xf6, 0xde, 0x70, 0x8a, + 0xf8, 0xa0, 0x79, 0x89, 0x39, 0x05, 0xdb, 0xb4, 0xc4, 0xba, 0x53, 0x29, + 0x87, 0x5f, 0xfa, 0xea, 0x6a, 0x17, 0xea, 0xe0, 0x4b, 0xd0, 0xce, 0x31, + 0x22, 0x57, 0x4a, 0x0c, 0xad, 0xb7, 0x18, 0x23, 0x69, 0xe1, 0xfa, 0xa5, + 0x7a, 0x31, 0x03, 0x9e, 0xe6, 0xc8, 0x4d, 0x2f, 0x98, 0x8b, 0x11, 0xce, + 0x2b, 0x43, 0xa9, 0xe2, 0x2a, 0x8b, 0xb8, 0xfc, 0x6a, 0xa9, 0xc8, 0xc9, + 0xc3, 0x69, 0x62, 0x46, 0x0d, 0x84, 0x4d, 0xad, 0x19, 0xe2, 0xf3, 0x4b, + 0xa9, 0x3e, 0x9e, 0x40, 0x9b, 0x00, 0x7a, 0x96, 0x45, 0xa9, 0x9e, 0x6d, + 0x87, 0xa9, 0x40, 0x25, 0x27, 0x83, 0xd2, 0x0b, 0xad, 0xe9, 0xb0, 0xa7, + 0xac, 0x6d, 0x05, 0x6d, 0xc9, 0x38, 0x6c, 0x09, 0xc8, 0xdf, 0x8e, 0x7e, + 0x12, 0xa5, 0x76, 0xdb, 0xdf, 0xa3, 0x48, 0x19, 0x48, 0x2b, 0xf1, 0x04, + 0xa5, 0x8f, 0x77, 0xfa, 0x90, 0x3a, 0x78, 0x53, 0x87, 0x05, 0xe9, 0xf4, + 0x75, 0x94, 0x34, 0x70, 0x36, 0x49, 0x2f, 0xc1, 0x8e, 0xf4, 0x42, 0xc3, + 0x9c, 0xed, 0x68, 0x49, 0x82, 0x1c, 0xec, 0x4c, 0x09, 0x69, 0xf4, 0x0b, + 0x3d, 0xc5, 0x9e, 0x46, 0x80, 0x45, 0x56, 0x7d, 0xa5, 0x67, 0xbd, 0xc7, + 0xe9, 0x11, 0xc1, 0xba, 0xc8, 0x85, 0xa1, 0xa4, 0xec, 0x13, 0xa4, 0xc1, + 0x21, 0x1c, 0xf3, 0x94, 0xbf, 0x23, 0xd9, 0x15, 0x6e, 0x3b, 0x62, 0x9b, + 0x9c, 0xdb, 0xc8, 0xb8, 0xdb, 0x84, 0x41, 0x39, 0x05, 0xbe, 0xc5, 0xed, + 0x11, 0xd2, 0x50, 0xeb, 0xcb, 0x01, 0x55, 0xe3, 0xaa, 0xca, 0xbb, 0x16, + 0xbc, 0xb3, 0x98, 0x71, 0x2f, 0x35, 0xdb, 0x9c, 0x7d, 0x32, 0x14, 0xec, + 0x13, 0x74, 0x32, 0x1d, 0x6b, 0x39, 0x21, 0xe2, 0x5e, 0x0a, 0xea, 0x25, + 0x64, 0x8a, 0x7a, 0x41, 0x34, 0x9a, 0x7a, 0x37, 0x4c, 0xd4, 0x49, 0x2b, + 0x2a, 0xd7, 0x54, 0xae, 0x82, 0x25, 0x4b, 0xee, 0xc9, 0x31, 0xb9, 0x97, + 0xc0, 0xf7, 0x17, 0xe4, 0xcc, 0x27, 0x93, 0x2f, 0x47, 0x55, 0x01, 0x21, + 0x60, 0xea, 0x08, 0x0b, 0xaa, 0x63, 0x8b, 0x73, 0x18, 0x3f, 0x17, 0x32, + 0x75, 0x6e, 0x09, 0x3c, 0x9a, 0x0b, 0x4e, 0xad, 0x74, 0x7e, 0x23, 0x94, + 0xb2, 0x72, 0x0b, 0x5a, 0x66, 0xa4, 0xa7, 0xab, 0xfd, 0xf3, 0x28, 0x41, + 0x88, 0x2e, 0x3c, 0xf4, 0x59, 0x54, 0xd5, 0x60, 0xea, 0x58, 0x9c, 0xc7, + 0x02, 0x53, 0x4b, 0xa5, 0x67, 0x22, 0xfe, 0xb7, 0x84, 0x96, 0xa7, 0xfa, + 0x6e, 0x6f, 0xc0, 0xab, 0xbb, 0xe0, 0x27, 0x3c, 0xe7, 0x31, 0x75, 0xc6, + 0x3b, 0xa0, 0x50, 0x03, 0xa4, 0x19, 0xf5, 0x11, 0x89, 0x14, 0x8c, 0x87, + 0x9f, 0x78, 0x5e, 0x43, 0xab, 0x88, 0x88, 0x0b, 0xcd, 0x23, 0x9d, 0x74, + 0x04, 0x9f, 0x4d, 0xd0, 0x2f, 0x1c, 0x13, 0xcd, 0x4b, 0xe1, 0xf3, 0x28, + 0x4d, 0x9b, 0x02, 0x69, 0x30, 0x01, 0x6c, 0x6e, 0xd2, 0xf4, 0x93, 0x1c, + 0x08, 0x93, 0x16, 0x3a, 0x23, 0x0c, 0xe2, 0x2a, 0x28, 0xe6, 0x9e, 0x41, + 0x3d, 0xf0, 0xa6, 0xad, 0xcc, 0x0d, 0xa5, 0xe6, 0x5b, 0xac, 0xec, 0xc9, + 0x02, 0xce, 0x34, 0x79, 0x29, 0xec, 0x5d, 0x32, 0xd2, 0x99, 0x0d, 0x1f, + 0x47, 0x55, 0x88, 0xfd, 0xfe, 0x28, 0x1d, 0x8b, 0x27, 0x8f, 0xa8, 0x9a, + 0x19, 0x47, 0x1a, 0x24, 0xca, 0xd5, 0x76, 0x35, 0xc5, 0x7c, 0x82, 0x38, + 0xd4, 0x76, 0x68, 0xa2, 0xfa, 0xd7, 0xaf, 0x13, 0xac, 0x83, 0x34, 0x65, + 0x00, 0x75, 0xbf, 0x94, 0x00, 0x5e, 0x0b, 0x16, 0x60, 0x0f, 0x2c, 0xbe, + 0x83, 0xb8, 0xb3, 0x9c, 0x03, 0x88, 0xb3, 0xd7, 0x84, 0x1c, 0x39, 0xcb, + 0xe1, 0xc2, 0xb0, 0x44, 0xbc, 0x32, 0x41, 0x22, 0x50, 0xb0, 0xab, 0x12, + 0x70, 0x64, 0x30, 0x61, 0x46, 0xdc, 0x2d, 0x98, 0x8f, 0x23, 0x85, 0x47, + 0x68, 0xdc, 0x54, 0x84, 0x88, 0x3d, 0x28, 0x72, 0xaa, 0x16, 0x33, 0x90, + 0x48, 0x22, 0xee, 0x42, 0x29, 0x65, 0xe9, 0x05, 0x87, 0xca, 0x4e, 0x4b, + 0xfe, 0x41, 0xc2, 0xea, 0x63, 0x0f, 0x5e, 0xb8, 0x8b, 0x4c, 0x96, 0xee, + 0x38, 0x19, 0x2d, 0x53, 0x6a, 0x6b, 0xc6, 0x56, 0xea, 0x7b, 0x32, 0x8a, + 0xed, 0x52, 0x66, 0x31, 0x2f, 0x99, 0x8a, 0xcd, 0x32, 0x4c, 0x50, 0xc9, + 0x14, 0xea, 0x3b, 0xb1, 0x8f, 0x54, 0x0e, 0xc6, 0x7e, 0xc7, 0x21, 0xab, + 0x59, 0xa8, 0x48, 0x54, 0xe4, 0x87, 0x68, 0xfa, 0xa5, 0x09, 0x46, 0xb4, + 0x71, 0x2d, 0xc2, 0xa7, 0xdd, 0x7b, 0x85, 0x2e, 0x89, 0x3d, 0x14, 0xbd, + 0x83, 0x4c, 0xee, 0x8f, 0xb2, 0x87, 0xb8, 0x3b, 0xc9, 0xe4, 0x5f, 0x45, + 0x55, 0x8e, 0x0c, 0x80, 0xf1, 0x1f, 0x45, 0x53, 0x1c, 0x5a, 0xfb, 0x40, + 0xf4, 0xc6, 0x02, 0x3a, 0x33, 0x4b, 0x29, 0xed, 0xd1, 0xdc, 0x0b, 0x0f, + 0x11, 0xd4, 0x15, 0x54, 0xb5, 0x6f, 0xd5, 0x3d, 0x5a, 0xf7, 0x66, 0xfd, + 0xa6, 0x7a, 0xd5, 0x52, 0x55, 0xbd, 0x49, 0x99, 0xff, 0x68, 0x2c, 0x62, + 0xe1, 0x41, 0x68, 0x43, 0x69, 0x0b, 0x52, 0xb8, 0xd7, 0x06, 0xcf, 0x2f, + 0x47, 0x6b, 0x26, 0x01, 0x8e, 0xde, 0x3a, 0xc6, 0x6e, 0xc3, 0x1a, 0x9d, + 0x89, 0xbd, 0x75, 0xa4, 0x78, 0x83, 0x4c, 0x26, 0xd6, 0x23, 0x6f, 0x45, + 0x39, 0x5a, 0xb6, 0x2f, 0xf7, 0xf8, 0x0f, 0x99, 0xb2, 0x1d, 0x3f, 0x7c, + 0x0f, 0x7f, 0x93, 0x8f, 0xa7, 0x2c, 0xa5, 0xd1, 0xd7, 0xc8, 0x03, 0x67, + 0x9f, 0xef, 0x36, 0x37, 0x36, 0x96, 0x2d, 0x6a, 0x2c, 0x9e, 0xd6, 0xda, + 0x68, 0x47, 0x6d, 0x9d, 0x73, 0x2d, 0x2d, 0x4b, 0xb8, 0x52, 0x1a, 0x89, + 0x5b, 0x6c, 0x67, 0xca, 0xb6, 0x08, 0xfd, 0xb2, 0x0d, 0xcb, 0xd8, 0xe5, + 0x5a, 0x04, 0xde, 0xf9, 0xc4, 0xdd, 0x84, 0xd8, 0xfd, 0xab, 0xfd, 0x71, + 0x5b, 0x35, 0x78, 0x60, 0xde, 0x7c, 0x8b, 0x8d, 0xc1, 0xb4, 0xf3, 0xe6, + 0x33, 0x65, 0x04, 0x7f, 0x73, 0xfe, 0xc5, 0x97, 0xf7, 0x2f, 0x3e, 0xdb, + 0xa8, 0xcf, 0x01, 0xef, 0x94, 0x27, 0xca, 0xb3, 0x92, 0xa5, 0x97, 0xbf, + 0x84, 0xa5, 0x1f, 0x70, 0x00, 0x6f, 0xb3, 0x37, 0x43, 0xdb, 0xfc, 0x7d, + 0xdc, 0xed, 0x9b, 0x16, 0x34, 0x86, 0x1b, 0x8f, 0x37, 0x66, 0x6d, 0xfa, + 0x85, 0xa3, 0x19, 0x9e, 0xe5, 0x16, 0xc3, 0x0e, 0xac, 0xd3, 0x86, 0x75, + 0xf2, 0x2b, 0xe8, 0xf7, 0x89, 0x1d, 0xbd, 0x76, 0x64, 0xe0, 0xb3, 0xca, + 0x50, 0x7a, 0x8c, 0xb4, 0xe5, 0xf6, 0x6c, 0x04, 0xa7, 0x59, 0x4e, 0x14, + 0x7f, 0xfb, 0x4c, 0x5b, 0x43, 0x57, 0xfb, 0xe2, 0x9c, 0x7d, 0xb5, 0x37, + 0xf5, 0x32, 0xc5, 0x06, 0xf9, 0x00, 0x6f, 0x07, 0x11, 0xd3, 0x9d, 0xe7, + 0x68, 0xca, 0x9e, 0x11, 0x4a, 0x95, 0x3f, 0xeb, 0x6d, 0x5b, 0x0e, 0x4e, + 0xb5, 0x44, 0x2a, 0x88, 0xb3, 0xfb, 0x14, 0xed, 0xad, 0x3d, 0xbd, 0xe3, + 0x57, 0xc0, 0x75, 0x66, 0x99, 0x62, 0xec, 0xbe, 0x11, 0x35, 0xd0, 0x77, + 0xfd, 0x08, 0x30, 0xb7, 0x98, 0xa9, 0xeb, 0x9e, 0x11, 0xd2, 0x44, 0xdf, + 0x8b, 0x47, 0x88, 0x08, 0x4c, 0x17, 0x57, 0xe9, 0x5b, 0xe8, 0x79, 0x4c, + 0x38, 0x2f, 0x93, 0x29, 0x85, 0xf5, 0xe3, 0x6b, 0xf9, 0x15, 0xa4, 0x02, + 0x65, 0x93, 0xf3, 0x21, 0x89, 0xa6, 0xa9, 0x1a, 0x69, 0x6b, 0xa0, 0xb5, + 0x73, 0xc1, 0x7d, 0xa8, 0x71, 0xe9, 0x25, 0x7e, 0xe5, 0xa2, 0x1c, 0xfb, + 0x52, 0xe9, 0x0e, 0x7e, 0xe5, 0xf9, 0x15, 0x61, 0x81, 0xe0, 0xa8, 0xe6, + 0x97, 0xb6, 0x35, 0x9c, 0x6f, 0x40, 0x2e, 0x7f, 0x8c, 0x8f, 0xa2, 0x16, + 0xd4, 0x7b, 0x44, 0x58, 0x2c, 0x31, 0x53, 0x13, 0x53, 0x73, 0x8a, 0x7f, + 0x7d, 0xc6, 0xe5, 0xc3, 0xe0, 0xc5, 0x2e, 0x9f, 0xf9, 0x2e, 0x5a, 0xd6, + 0xdc, 0x91, 0x03, 0x3c, 0xc2, 0x5e, 0x7f, 0x8e, 0xa3, 0xbe, 0xbb, 0x46, + 0x72, 0x8b, 0xf7, 0x9f, 0x29, 0x55, 0x52, 0x94, 0x8c, 0xa6, 0xb8, 0x71, + 0xa4, 0x0d, 0x71, 0x31, 0x41, 0xba, 0xb0, 0xa2, 0x45, 0xb8, 0xa9, 0xdb, + 0xb1, 0xd2, 0x64, 0x29, 0x38, 0xe1, 0xaf, 0x7f, 0x76, 0x45, 0x5b, 0x43, + 0xdd, 0x0a, 0x28, 0x29, 0x96, 0x16, 0xe6, 0xec, 0xad, 0xdd, 0x7e, 0x97, + 0x25, 0x48, 0x53, 0xa5, 0x48, 0x8e, 0x95, 0xb7, 0x23, 0x2c, 0xb5, 0x2b, + 0x16, 0xdd, 0xd5, 0xfa, 0x2f, 0xf0, 0xd4, 0xaf, 0x38, 0xbf, 0x82, 0xb8, + 0xeb, 0xeb, 0x93, 0xfe, 0xfa, 0xfa, 0x64, 0x8b, 0x0e, 0x45, 0x39, 0xae, + 0x3b, 0x8a, 0x25, 0x35, 0x88, 0x96, 0x16, 0xe4, 0xa7, 0xcb, 0xa3, 0x1e, + 0x41, 0x8a, 0x46, 0x68, 0x69, 0x0d, 0xc4, 0xdd, 0x56, 0xfb, 0x71, 0xf4, + 0xc2, 0x72, 0x6a, 0xd5, 0xbf, 0x7d, 0x99, 0xd8, 0x46, 0x3a, 0xd5, 0xb6, + 0x25, 0xca, 0x5c, 0x18, 0xc0, 0x41, 0xa4, 0xdb, 0xcb, 0xf8, 0xcc, 0xc3, + 0xe7, 0x71, 0x4a, 0xc3, 0x1d, 0x6a, 0x30, 0x02, 0xb9, 0x11, 0x8e, 0x05, + 0x3b, 0xe9, 0x18, 0xf8, 0xe5, 0x70, 0x5f, 0x34, 0x88, 0x7c, 0x2f, 0x11, + 0x6f, 0x1f, 0x4e, 0x62, 0xfa, 0xe7, 0xc3, 0xc0, 0x14, 0x7b, 0x1b, 0xdb, + 0x83, 0x9d, 0xc9, 0xf0, 0x9f, 0x0e, 0x6b, 0x20, 0xbf, 0x98, 0x91, 0x68, + 0xcf, 0x04, 0x3b, 0x69, 0x8a, 0xa7, 0x87, 0x77, 0x14, 0xc7, 0x95, 0xde, + 0x69, 0x19, 0xd6, 0x15, 0x7f, 0xae, 0xb8, 0xc2, 0xc3, 0x2a, 0x78, 0xc9, + 0xdb, 0xd3, 0xae, 0x06, 0x70, 0xfe, 0x5d, 0xd6, 0x28, 0xd4, 0x7e, 0x34, + 0xb1, 0x42, 0xab, 0x39, 0x49, 0x5d, 0x7f, 0x4e, 0x10, 0xa5, 0xec, 0xae, + 0x84, 0x53, 0xcb, 0x2a, 0x21, 0x0f, 0x0f, 0x43, 0xf1, 0x80, 0xfc, 0xb1, + 0x26, 0xe9, 0xbb, 0x5f, 0xf1, 0x31, 0x45, 0x53, 0x04, 0x46, 0xe9, 0xb7, + 0x57, 0x12, 0xf5, 0xb9, 0x7f, 0x7b, 0x88, 0x6a, 0x36, 0x60, 0xe3, 0xeb, + 0xde, 0x42, 0x9e, 0xc3, 0xf8, 0xb8, 0x40, 0xa3, 0xb6, 0x2b, 0x3d, 0x38, + 0x1b, 0x6d, 0xa1, 0x2e, 0x8d, 0x27, 0x1b, 0x47, 0x22, 0x01, 0x6e, 0x2b, + 0xeb, 0xb6, 0x6e, 0xa5, 0xdf, 0xc6, 0xc6, 0x8e, 0xfa, 0x99, 0x51, 0x3f, + 0x85, 0x9d, 0x14, 0x6d, 0x83, 0x5b, 0xb8, 0xc3, 0x88, 0x47, 0x17, 0x20, + 0xe4, 0x68, 0xef, 0x5d, 0x4c, 0x90, 0xb7, 0xbd, 0x79, 0x2d, 0x33, 0x3d, + 0x82, 0xc6, 0xf3, 0x79, 0x54, 0xed, 0xd3, 0xd4, 0x64, 0xf9, 0xe9, 0xb3, + 0xc0, 0x1f, 0xf6, 0x1f, 0xf7, 0x67, 0xd5, 0x2e, 0xa8, 0x0d, 0xd7, 0x06, + 0x67, 0x37, 0xe2, 0x1f, 0x5c, 0x84, 0x5e, 0x16, 0x1f, 0xb0, 0xb3, 0x3e, + 0xb6, 0xe6, 0xf5, 0x2b, 0xdf, 0xf9, 0x09, 0xf3, 0x56, 0x58, 0x18, 0x90, + 0x95, 0xfa, 0x09, 0x48, 0x8d, 0xf8, 0xb0, 0x35, 0xa6, 0x90, 0x37, 0xa7, + 0xa7, 0x7d, 0x9c, 0x93, 0x74, 0x67, 0x05, 0x83, 0xb3, 0x4d, 0xfc, 0x60, + 0x34, 0x54, 0x08, 0x36, 0xc6, 0x77, 0x94, 0xdb, 0x06, 0xc4, 0x4f, 0xd3, + 0x7a, 0x00, 0x26, 0x63, 0x8c, 0x82, 0xc9, 0xe8, 0x28, 0x16, 0xfe, 0x91, + 0x48, 0xf0, 0xfc, 0x5a, 0x5a, 0xa6, 0xa9, 0x33, 0x19, 0x73, 0x7a, 0x34, + 0xe6, 0x3c, 0xc6, 0xb4, 0x35, 0x26, 0x63, 0x00, 0xfa, 0x30, 0xce, 0x68, + 0x1b, 0x07, 0x79, 0x90, 0x8a, 0x4c, 0x77, 0x4e, 0x7f, 0x6e, 0xf5, 0x4c, + 0xef, 0x54, 0x74, 0xcd, 0xee, 0xd7, 0x44, 0xdc, 0x6c, 0xa6, 0x0a, 0xb5, + 0xc6, 0x00, 0x94, 0xa6, 0x9f, 0x9e, 0x61, 0x77, 0x04, 0x0c, 0x9e, 0x83, + 0x82, 0x41, 0xde, 0x17, 0xc8, 0x54, 0x67, 0xa6, 0x6e, 0x16, 0xd4, 0xf2, + 0x67, 0xf6, 0xf3, 0x81, 0xa3, 0x8c, 0xc1, 0x13, 0x11, 0xac, 0x92, 0xa9, + 0x66, 0x97, 0x60, 0x96, 0xe8, 0xf7, 0xa7, 0xf4, 0xea, 0xf4, 0x5b, 0x0d, + 0xfe, 0xf4, 0x6a, 0x83, 0x7f, 0x1c, 0xfc, 0x22, 0xf0, 0x13, 0xef, 0xa0, + 0xdc, 0xe5, 0xb0, 0xe7, 0x36, 0x13, 0x83, 0xd7, 0x6e, 0x2f, 0xf4, 0xef, + 0xf5, 0x67, 0xf8, 0xed, 0x01, 0x28, 0x19, 0x3a, 0x7d, 0xc1, 0xaf, 0xe3, + 0xb3, 0xfc, 0x7d, 0x9d, 0xa8, 0xbd, 0x91, 0x8b, 0x48, 0x69, 0x68, 0x77, + 0x76, 0x31, 0x1e, 0xe5, 0x8b, 0x5f, 0x17, 0x3e, 0x31, 0xf0, 0x34, 0xf2, + 0x4c, 0x8d, 0x08, 0x2a, 0xef, 0xf1, 0x3a, 0xe4, 0x8a, 0x8d, 0x6a, 0x0f, + 0xe3, 0xb3, 0x04, 0x18, 0xdf, 0x62, 0xa5, 0xcd, 0xaf, 0xd1, 0xf9, 0x69, + 0x0c, 0x53, 0x41, 0xa3, 0x2d, 0xb3, 0xa6, 0x4b, 0x6d, 0xea, 0xc8, 0x9c, + 0x63, 0xf2, 0x67, 0x56, 0xb1, 0xfe, 0x5e, 0x5b, 0xc6, 0x9c, 0x2e, 0x16, + 0x4a, 0x34, 0x92, 0xcd, 0x8f, 0x63, 0x5e, 0x99, 0xd7, 0xe0, 0xfd, 0x88, + 0x05, 0x7f, 0x3c, 0x3a, 0x60, 0x6b, 0x74, 0x74, 0xc1, 0x42, 0xef, 0x7c, + 0x56, 0xef, 0x6b, 0x12, 0xd4, 0xc7, 0x38, 0x7f, 0x22, 0x7e, 0x22, 0xd1, + 0xc8, 0xf7, 0xa8, 0x3f, 0x8d, 0x6a, 0x6a, 0x2c, 0x98, 0x02, 0x8e, 0xa8, + 0x3d, 0x43, 0x88, 0x29, 0x9d, 0x8d, 0x78, 0x60, 0xaf, 0xda, 0x43, 0xeb, + 0x41, 0xbd, 0x1d, 0x68, 0x5f, 0x9b, 0xa0, 0xd1, 0x61, 0xf0, 0x1d, 0x53, + 0x5b, 0xfc, 0x06, 0x1f, 0x4c, 0x30, 0x4a, 0xa4, 0x50, 0x5f, 0x33, 0xc1, + 0x7b, 0xba, 0x56, 0x57, 0x53, 0xe7, 0xb1, 0xd4, 0x2d, 0xaa, 0xdb, 0x5d, + 0x07, 0x76, 0x4a, 0x57, 0xc1, 0xce, 0x33, 0xb5, 0xfd, 0xd4, 0x9e, 0xc6, + 0xb2, 0x28, 0x8c, 0xc7, 0xbb, 0xb4, 0x47, 0x26, 0xce, 0xe8, 0xbb, 0xed, + 0xa0, 0x43, 0xe3, 0xa3, 0x5f, 0x0e, 0xec, 0xc8, 0x03, 0x4f, 0xfb, 0xd9, + 0x6a, 0xb6, 0x26, 0xc3, 0xbf, 0x18, 0xb1, 0x3b, 0x74, 0x1a, 0xdb, 0xe7, + 0xc1, 0xb6, 0x1f, 0x19, 0x00, 0xf0, 0x33, 0x1e, 0xde, 0x57, 0x50, 0x13, + 0xec, 0xb0, 0xf8, 0xf9, 0x9a, 0x82, 0x39, 0x63, 0xa0, 0xc0, 0xc7, 0xfb, + 0x39, 0xd8, 0x19, 0xd8, 0x8a, 0x98, 0xa4, 0xdf, 0x93, 0xf6, 0x08, 0x05, + 0xc7, 0x47, 0xe2, 0xf2, 0xa0, 0x1d, 0xc3, 0x0f, 0x05, 0x7a, 0x48, 0xa3, + 0x7b, 0x50, 0xf6, 0x38, 0xf2, 0x7c, 0xf9, 0x55, 0x91, 0xfb, 0x16, 0xdf, + 0x67, 0xb9, 0xef, 0xf4, 0xb2, 0x5c, 0x5f, 0x8b, 0x30, 0xe6, 0x78, 0xee, + 0x9c, 0xdc, 0xb9, 0xcf, 0x06, 0xba, 0x1c, 0x54, 0x4b, 0xb2, 0xf4, 0x3f, + 0x8f, 0x2d, 0x7d, 0x6f, 0x04, 0xc7, 0x22, 0x3e, 0x7f, 0x1f, 0xe1, 0xe6, + 0x70, 0xbe, 0xdd, 0x42, 0xfa, 0xf1, 0x60, 0xa7, 0xee, 0xcf, 0x2d, 0xb3, + 0x4f, 0x44, 0x51, 0x27, 0x09, 0xe8, 0x26, 0x53, 0xcb, 0x27, 0x11, 0xff, + 0x70, 0xc4, 0x06, 0x67, 0xa3, 0x89, 0xf8, 0x5f, 0x47, 0x06, 0xa2, 0xba, + 0x3f, 0xb6, 0xcc, 0x46, 0x5d, 0x08, 0xfb, 0xe4, 0xf5, 0x3f, 0x0d, 0x8e, + 0x5c, 0xed, 0x97, 0x91, 0x8d, 0x37, 0xc2, 0x7e, 0xa4, 0xc1, 0x5f, 0x15, + 0x2a, 0xb8, 0x21, 0x10, 0x23, 0x9e, 0xbd, 0xf4, 0xbb, 0x18, 0xfd, 0x1e, + 0x9c, 0xfc, 0xfe, 0xad, 0xc4, 0x29, 0xdf, 0x87, 0x3b, 0xe0, 0xb7, 0xf4, + 0xdb, 0x2d, 0x8e, 0x9c, 0xaa, 0x44, 0xbc, 0x2f, 0xe1, 0xc7, 0x30, 0x52, + 0xc5, 0xda, 0x89, 0x8f, 0x9b, 0xdd, 0x88, 0xee, 0x89, 0x39, 0xe8, 0xf7, + 0x2d, 0x09, 0x70, 0xb3, 0x01, 0xa8, 0x9f, 0xf8, 0xc4, 0x6b, 0xdc, 0xd6, + 0xaf, 0xdd, 0x19, 0x35, 0xe1, 0x35, 0xa2, 0x2e, 0xeb, 0x98, 0x69, 0xd9, + 0xed, 0xcb, 0xa0, 0x44, 0x2d, 0x25, 0xa2, 0xf4, 0xff, 0xf6, 0x35, 0xa6, + 0x35, 0xc1, 0xd9, 0x6c, 0x07, 0xea, 0x33, 0x12, 0xd8, 0xba, 0xbc, 0x10, + 0x3b, 0xd4, 0x87, 0xa3, 0xa9, 0xb3, 0xab, 0x32, 0xd6, 0x91, 0xbd, 0xfa, + 0xce, 0xd5, 0xdf, 0x5e, 0x33, 0x76, 0x4d, 0x22, 0x7e, 0x29, 0x91, 0xbd, + 0xec, 0xce, 0x65, 0xdf, 0xbe, 0x6f, 0xec, 0x7d, 0xb1, 0x4e, 0xfa, 0x6d, + 0x3e, 0x8b, 0x0f, 0x76, 0xe4, 0x84, 0xd2, 0xe7, 0x92, 0x09, 0x54, 0xe7, + 0x4a, 0xab, 0x8e, 0x00, 0x71, 0x1f, 0x98, 0x47, 0xe5, 0x4c, 0x8a, 0xef, + 0xd0, 0xd2, 0x14, 0x84, 0x93, 0x19, 0x31, 0xf8, 0x38, 0x7f, 0xb0, 0x93, + 0x4c, 0xf8, 0xf2, 0xac, 0x5e, 0xf1, 0x37, 0x3a, 0x08, 0x50, 0x4c, 0x3e, + 0xd0, 0xc7, 0x4c, 0xf8, 0x54, 0xfe, 0x28, 0xfa, 0xc7, 0xe3, 0x60, 0xbb, + 0xc9, 0x06, 0xb6, 0x39, 0x6e, 0x80, 0xb7, 0xaf, 0x03, 0xdb, 0x82, 0x59, + 0x00, 0xda, 0x0e, 0x7f, 0x25, 0xd9, 0x6a, 0x30, 0x30, 0xae, 0x0f, 0x4a, + 0x07, 0xe4, 0xa3, 0xed, 0x9b, 0x75, 0xec, 0x71, 0x66, 0xab, 0x67, 0x2b, + 0xb0, 0x26, 0x2f, 0x62, 0x25, 0x40, 0x6a, 0xe6, 0xcd, 0x53, 0x35, 0x69, + 0x3b, 0x69, 0xde, 0x2c, 0xe4, 0x25, 0xa6, 0xaa, 0x9c, 0x10, 0xd2, 0xdf, + 0x30, 0x01, 0x32, 0x21, 0x4b, 0x4e, 0x9b, 0x73, 0x87, 0x03, 0x65, 0x6d, + 0x6c, 0x56, 0xdf, 0x18, 0xde, 0x58, 0x43, 0xbf, 0x12, 0xd5, 0x29, 0x30, + 0x39, 0xea, 0xce, 0xd7, 0x52, 0x18, 0x7e, 0x35, 0xac, 0x43, 0x98, 0x4c, + 0x08, 0x53, 0xfc, 0x6c, 0xa3, 0x83, 0x7e, 0x07, 0xbb, 0xae, 0xef, 0xf3, + 0xe8, 0x82, 0x4a, 0x80, 0x3f, 0x9e, 0x00, 0xdb, 0x3b, 0xd7, 0xc0, 0xf2, + 0x7f, 0x0c, 0xc7, 0x89, 0x6f, 0xfa, 0xa2, 0xe9, 0xeb, 0xbe, 0x48, 0xe2, + 0xbc, 0xa9, 0xf0, 0x9b, 0x7e, 0xa1, 0x6e, 0x3a, 0xe6, 0x5c, 0x1d, 0xaa, + 0x52, 0xe3, 0x29, 0x15, 0xa4, 0x78, 0x45, 0x6d, 0x8e, 0xac, 0x0a, 0x18, + 0x03, 0x6d, 0x02, 0x27, 0xb3, 0xd3, 0x59, 0x17, 0x5b, 0xa6, 0x2a, 0xfd, + 0xaa, 0xfb, 0xce, 0x3c, 0x28, 0x4d, 0x93, 0x98, 0x90, 0x31, 0xb4, 0x0b, + 0xb5, 0x59, 0x32, 0x85, 0xf0, 0x64, 0x1a, 0xdb, 0xfb, 0xe6, 0x5d, 0xc4, + 0xfd, 0xc7, 0xbb, 0xf6, 0x21, 0xbf, 0x38, 0x24, 0xa0, 0x3e, 0x6b, 0x73, + 0x75, 0xde, 0x99, 0xf7, 0x49, 0xd4, 0x64, 0x1d, 0x88, 0xaa, 0xf8, 0x3f, + 0xb4, 0xc7, 0x3a, 0x54, 0x1e, 0x28, 0x9d, 0x26, 0x81, 0x33, 0x4d, 0x52, + 0x85, 0xc0, 0xf9, 0x6d, 0x29, 0x22, 0x94, 0x49, 0xaa, 0x02, 0xb6, 0x97, + 0xfa, 0xe6, 0x49, 0x61, 0xa1, 0x54, 0x22, 0x2e, 0x9b, 0x10, 0x97, 0x13, + 0x85, 0x25, 0x9e, 0x54, 0xa6, 0xc4, 0x9b, 0xca, 0xa6, 0x7a, 0x27, 0x00, + 0x09, 0xf0, 0xb7, 0xce, 0xf1, 0xec, 0x30, 0xef, 0xf0, 0x3e, 0x6b, 0x7e, + 0xd6, 0x6b, 0xbf, 0x35, 0xc5, 0xeb, 0x16, 0x52, 0x64, 0xd6, 0x45, 0x02, + 0xb9, 0xb7, 0x19, 0xe1, 0x3d, 0xf3, 0x4a, 0xcf, 0x0e, 0xef, 0x39, 0x8c, + 0xa1, 0xe1, 0x57, 0x94, 0x92, 0x59, 0xb9, 0xa4, 0x97, 0xb8, 0xa8, 0xab, + 0x10, 0xeb, 0xe8, 0x97, 0x91, 0x16, 0x9c, 0x06, 0x25, 0xa6, 0x5f, 0x42, + 0xbd, 0x4d, 0xa9, 0xef, 0x0b, 0xac, 0xcb, 0x84, 0x71, 0x4c, 0x20, 0xc5, + 0x67, 0xac, 0x3e, 0xce, 0x85, 0xbd, 0x29, 0x82, 0x06, 0x4b, 0x65, 0x02, + 0x5a, 0x5f, 0xd2, 0xd7, 0xa7, 0xe4, 0xe8, 0x95, 0x92, 0x25, 0x0d, 0xca, + 0x3d, 0x28, 0xd1, 0x4f, 0x51, 0x39, 0x38, 0x32, 0x32, 0x42, 0x79, 0x3a, + 0xf2, 0x09, 0xe5, 0x7b, 0xaa, 0x1a, 0xd2, 0x42, 0x30, 0x49, 0x2f, 0xfd, + 0x14, 0x75, 0xdd, 0x14, 0x20, 0xbd, 0xfb, 0x04, 0xad, 0x44, 0xdc, 0x96, + 0x10, 0x94, 0xf6, 0x23, 0x66, 0x26, 0x60, 0x9a, 0x7f, 0xc8, 0xc5, 0x96, + 0x60, 0x27, 0xd8, 0x86, 0xa2, 0xc9, 0x3c, 0xd9, 0xd7, 0xe4, 0xd1, 0x8f, + 0xe6, 0x51, 0x7f, 0x9d, 0x87, 0xa6, 0x4d, 0xe6, 0xfb, 0x54, 0xee, 0xc3, + 0x3a, 0xe3, 0x58, 0x27, 0x5d, 0xeb, 0xa1, 0xab, 0x31, 0x75, 0x64, 0x21, + 0x24, 0x06, 0xe4, 0x73, 0x74, 0x5d, 0xc7, 0x12, 0x75, 0x4e, 0xe0, 0xed, + 0x79, 0xac, 0x7b, 0x07, 0xca, 0x11, 0xc2, 0x67, 0x05, 0xe9, 0x1a, 0x8c, + 0xa3, 0xf3, 0xc0, 0xb6, 0xab, 0x04, 0xd9, 0x17, 0x01, 0x93, 0xa9, 0x83, + 0xf1, 0x11, 0x37, 0x95, 0x5e, 0x5d, 0x95, 0xbb, 0x94, 0xef, 0xef, 0xb1, + 0x0e, 0x81, 0x63, 0x91, 0xfb, 0x3f, 0x76, 0x64, 0x09, 0x1b, 0x11, 0xc8, + 0xa9, 0x44, 0xbc, 0x64, 0x24, 0x7b, 0x3c, 0x57, 0x34, 0x75, 0xab, 0x7b, + 0x6b, 0x66, 0x75, 0xcb, 0x6c, 0xf7, 0x56, 0x55, 0x53, 0x46, 0xf5, 0xd4, + 0xad, 0xd4, 0xc5, 0x34, 0xa5, 0x8f, 0xba, 0xd2, 0xaa, 0x49, 0x13, 0x75, + 0xd1, 0xf9, 0x88, 0xce, 0x84, 0x4a, 0x6c, 0x99, 0xcd, 0xe0, 0xd3, 0x88, + 0x14, 0xdc, 0xcd, 0x97, 0xc0, 0x7c, 0x86, 0xec, 0xde, 0x3b, 0xfb, 0xc8, + 0xec, 0x44, 0xfc, 0xf7, 0x09, 0xfa, 0x9d, 0xbb, 0xab, 0xb2, 0x1a, 0xe9, + 0xf4, 0x96, 0x85, 0x00, 0xf3, 0x6f, 0x01, 0xa8, 0xf4, 0xe2, 0x98, 0xc6, + 0x7a, 0xc7, 0x61, 0x9d, 0x9b, 0xb1, 0x6e, 0xd5, 0xce, 0xab, 0x35, 0x7f, + 0x32, 0x9c, 0x5d, 0xc4, 0x15, 0xba, 0xb6, 0x3a, 0xd1, 0xbe, 0x6f, 0x99, + 0xed, 0x54, 0xea, 0x73, 0x6d, 0xa5, 0x2e, 0xd2, 0x94, 0x36, 0xea, 0x4a, + 0xad, 0x86, 0x26, 0xea, 0xa2, 0x36, 0x41, 0x63, 0x82, 0xd6, 0x4a, 0xf0, + 0x99, 0x8e, 0xac, 0x46, 0xd5, 0x0a, 0xe8, 0xda, 0x8f, 0xb5, 0x3e, 0xae, + 0xd4, 0xfa, 0x75, 0x9d, 0xf3, 0x92, 0x75, 0xce, 0x6b, 0xa8, 0x5f, 0x63, + 0xbb, 0xed, 0x8e, 0x99, 0x70, 0x1d, 0x4c, 0x9a, 0x04, 0x2b, 0x1b, 0xee, + 0xbf, 0x7f, 0xe5, 0xbd, 0xcb, 0xd6, 0x03, 0x24, 0x46, 0xff, 0xe8, 0x5a, + 0x95, 0xa5, 0xa6, 0x5f, 0xe6, 0xbe, 0x6b, 0x5b, 0x5d, 0x71, 0xd8, 0x75, + 0xaa, 0xa8, 0x69, 0xe6, 0x99, 0x07, 0xbf, 0xb8, 0x7d, 0xc5, 0x8a, 0x85, + 0xb5, 0xed, 0x73, 0x6f, 0x5c, 0xab, 0x9e, 0x47, 0xd7, 0x50, 0xcc, 0x0a, + 0xa7, 0xc7, 0x3e, 0x6c, 0xfb, 0xcb, 0x5f, 0x1e, 0x7f, 0xa9, 0xf6, 0xbd, + 0x23, 0x6f, 0x2e, 0x15, 0x4f, 0x1c, 0x3b, 0xfe, 0x83, 0xd0, 0x79, 0xc3, + 0xde, 0x9c, 0xcf, 0x3b, 0x3b, 0x4d, 0x19, 0x99, 0xa0, 0xd3, 0xea, 0x35, + 0x06, 0x75, 0x0a, 0x6b, 0x54, 0xa5, 0x32, 0x69, 0x24, 0x1d, 0x51, 0xce, + 0xa0, 0xbd, 0xc7, 0x82, 0x1a, 0xb4, 0xa0, 0x47, 0x2c, 0x67, 0x80, 0x19, + 0xec, 0x50, 0x06, 0x33, 0xa1, 0x16, 0x36, 0xc1, 0x1b, 0x40, 0xc8, 0x26, + 0x42, 0x18, 0xa2, 0x22, 0x2c, 0xd1, 0x10, 0x1d, 0x31, 0x12, 0x13, 0xe1, + 0x88, 0x8d, 0xb8, 0x88, 0x87, 0xf8, 0x95, 0xb5, 0x42, 0x84, 0x61, 0x54, + 0x2a, 0x96, 0x55, 0xab, 0x35, 0x1a, 0xad, 0x56, 0xa7, 0xd3, 0xeb, 0x0d, + 0x86, 0x94, 0x14, 0xa3, 0x31, 0x35, 0x35, 0x59, 0xaa, 0x06, 0xcb, 0xd5, + 0x61, 0xc9, 0x06, 0x48, 0xc1, 0xd2, 0xd3, 0xb1, 0xfc, 0x2c, 0x18, 0x07, + 0x56, 0xc8, 0x07, 0x1e, 0x55, 0x35, 0x37, 0x54, 0x80, 0x17, 0x16, 0x40, + 0x3d, 0xac, 0x87, 0x2d, 0xd0, 0x06, 0x6f, 0xc1, 0x05, 0x60, 0xc8, 0x37, + 0xab, 0xc5, 0x08, 0xa1, 0xe5, 0xd3, 0x1a, 0x68, 0x1d, 0xb4, 0x16, 0x35, + 0x2a, 0x57, 0xf3, 0xef, 0x5d, 0xf9, 0xed, 0x86, 0xfb, 0x03, 0xb3, 0xee, + 0xad, 0xab, 0x5e, 0xbd, 0x6c, 0x0d, 0xd4, 0xad, 0x59, 0x73, 0x7f, 0xf9, + 0x77, 0x1e, 0x2a, 0x9f, 0xb2, 0xd6, 0x35, 0xd5, 0x05, 0x65, 0x93, 0x26, + 0x4f, 0x42, 0x55, 0x07, 0x51, 0x09, 0x6b, 0xee, 0xaf, 0x85, 0x99, 0x0f, + 0xdc, 0x67, 0x2b, 0x73, 0xd9, 0xca, 0x5d, 0xe5, 0xe5, 0x40, 0xd7, 0x2b, + 0xbd, 0x9a, 0xb8, 0xf1, 0x95, 0xf1, 0xa3, 0x6b, 0x97, 0xce, 0x6d, 0xde, + 0xba, 0x31, 0x6b, 0xd4, 0x7d, 0x3c, 0xf6, 0x80, 0xc0, 0xa2, 0xbb, 0xaa, + 0x76, 0xdd, 0x52, 0x5b, 0xed, 0xfa, 0xf5, 0xf7, 0xae, 0xbb, 0x1f, 0xde, + 0x9d, 0x91, 0x5c, 0x3f, 0xa4, 0xac, 0x35, 0x1a, 0x7d, 0xcf, 0x43, 0x1e, + 0x46, 0xf9, 0xd8, 0x1d, 0xf8, 0xcc, 0xc7, 0x67, 0xee, 0x02, 0x7c, 0xb0, + 0xef, 0x16, 0x4c, 0x06, 0xf0, 0x4e, 0xfe, 0x06, 0xf2, 0x7f, 0x22, 0xbf, + 0xbb, 0x37, 0x1f, 0x6c, 0x97, 0xf0, 0x69, 0x40, 0xf7, 0x34, 0xf2, 0x4d, + 0x59, 0xff, 0xfd, 0xfb, 0xef, 0xdf, 0x7f, 0xff, 0xfe, 0xfb, 0xf7, 0xdf, + 0xbf, 0xff, 0xfe, 0xfd, 0xf7, 0xef, 0xff, 0x7b, 0x7f, 0x7f, 0xeb, 0x4a, + 0x4b, 0xf9, 0x2f, 0x16, 0xfe, 0xfb, 0xf7, 0xdf, 0xbf, 0xff, 0xfe, 0xfd, + 0xf7, 0xef, 0xbf, 0x7f, 0xff, 0xfd, 0xfb, 0xef, 0xdf, 0x7f, 0xff, 0xfe, + 0xfb, 0xf7, 0xdf, 0xbf, 0xff, 0xfe, 0xfd, 0xf7, 0xef, 0xbf, 0x7f, 0xff, + 0xfd, 0xfb, 0x7f, 0xf9, 0x1f, 0xdd, 0xff, 0xee, 0x01, 0xd3, 0x5b, 0xf8, + 0xbc, 0x83, 0xcf, 0x1b, 0xff, 0x8b, 0xe7, 0xf7, 0xd7, 0xb8, 0x8f, 0xe2, + 0xf3, 0x1e, 0x3e, 0x7f, 0xfa, 0x7f, 0xf8, 0xf9, 0xd7, 0xfd, 0xef, 0xbe, + 0xaf, 0xf7, 0xbf, 0xcf, 0x51, 0x13, 0x13, 0x7d, 0x26, 0xcf, 0xbc, 0xba, + 0xff, 0xdd, 0x7e, 0xcd, 0xfe, 0xf7, 0x7c, 0x65, 0xff, 0xfb, 0x75, 0xff, + 0xb6, 0xff, 0xdd, 0x52, 0x6d, 0xbd, 0x66, 0xff, 0xbb, 0xb9, 0x7a, 0xeb, + 0xec, 0xab, 0xcf, 0xbf, 0xee, 0x7f, 0xa7, 0xe5, 0x76, 0x21, 0xe6, 0x1e, + 0x35, 0x82, 0xcd, 0x94, 0x41, 0xbe, 0xde, 0xf3, 0xae, 0xb8, 0xff, 0x6d, + 0xcf, 0x3b, 0x13, 0x73, 0xfc, 0xc7, 0x3d, 0xef, 0x5b, 0x31, 0xef, 0xe4, + 0x1c, 0xb0, 0xdd, 0x72, 0x2f, 0x98, 0x7e, 0x51, 0x05, 0xa6, 0x5b, 0x96, + 0x81, 0x89, 0xee, 0x79, 0xff, 0xbf, 0xda, 0x93, 0x4e, 0xeb, 0xa2, 0x0f, + 0x2d, 0xf7, 0x7f, 0xb5, 0x27, 0xfd, 0xda, 0x74, 0xff, 0xbb, 0x3d, 0xe9, + 0x52, 0x6a, 0x32, 0x5d, 0xdf, 0x10, 0x98, 0xfe, 0x57, 0x7b, 0xd2, 0x4f, + 0x60, 0x3a, 0x9a, 0x26, 0xd8, 0x31, 0x50, 0x68, 0x98, 0x93, 0x72, 0xab, + 0x23, 0xb0, 0x0a, 0x5c, 0x60, 0xa8, 0x86, 0x98, 0xd4, 0x4f, 0xbf, 0xf3, + 0x0f, 0xf5, 0x3b, 0x02, 0x2e, 0x58, 0x90, 0xa3, 0xa9, 0xe6, 0xfd, 0x10, + 0xfb, 0x9d, 0x12, 0xf6, 0x79, 0x7f, 0xb0, 0x73, 0x72, 0x36, 0xd8, 0x0a, + 0xd2, 0x92, 0x79, 0xd5, 0xc3, 0x60, 0x3a, 0x67, 0x37, 0x75, 0x30, 0x55, + 0xd5, 0x0c, 0xc4, 0xf4, 0x7d, 0xb4, 0x6c, 0x1a, 0x67, 0xea, 0x50, 0x05, + 0x7a, 0x1a, 0x28, 0xe4, 0xaa, 0x47, 0xe8, 0x6a, 0x61, 0xe2, 0x56, 0xdd, + 0x1f, 0x9c, 0x1d, 0x9c, 0x9d, 0xd5, 0xb1, 0xa2, 0x92, 0x09, 0x9c, 0x5a, + 0xab, 0x75, 0xdf, 0x11, 0x30, 0x03, 0x71, 0xec, 0x9d, 0x3d, 0xb6, 0xf3, + 0x49, 0x5e, 0x5f, 0x63, 0xea, 0xc8, 0x0c, 0xf4, 0x40, 0x44, 0x30, 0xc8, + 0x5a, 0x1f, 0xdd, 0x8d, 0xab, 0x91, 0xe9, 0x2e, 0xe8, 0x60, 0xc2, 0x0e, + 0x2a, 0x6c, 0x4c, 0xf2, 0x5b, 0x6d, 0x17, 0x0b, 0xb6, 0xd7, 0x2c, 0x60, + 0xbb, 0x53, 0x00, 0xc8, 0xea, 0x00, 0x9e, 0x05, 0x1d, 0xd8, 0xfd, 0xfc, + 0x5a, 0x72, 0x20, 0x25, 0xf6, 0xde, 0x10, 0x14, 0xeb, 0x64, 0x89, 0xb7, + 0x6a, 0xac, 0x01, 0x12, 0x89, 0x08, 0xac, 0x64, 0x0b, 0xa4, 0xc4, 0x3e, + 0x1c, 0x42, 0x8c, 0xac, 0xb5, 0xc1, 0xd8, 0x4e, 0x84, 0x67, 0x03, 0x0b, + 0x14, 0x53, 0x80, 0xe1, 0x8f, 0x0e, 0x61, 0x67, 0x76, 0x6e, 0xec, 0x60, + 0x81, 0x79, 0xa1, 0x18, 0x52, 0xab, 0x13, 0xf1, 0xbf, 0x26, 0xf8, 0x47, + 0x72, 0xf2, 0x8c, 0x12, 0x14, 0x38, 0x37, 0xb4, 0x09, 0x74, 0x55, 0xe9, + 0xdf, 0x72, 0xcb, 0xe8, 0xf7, 0xd4, 0xd8, 0xcb, 0x89, 0xbd, 0x82, 0x46, + 0x9a, 0xac, 0xac, 0x64, 0x3c, 0x93, 0xb0, 0x01, 0x7b, 0x24, 0xd8, 0x49, + 0xd7, 0x25, 0x7e, 0x15, 0x7d, 0x19, 0xdb, 0xe9, 0xc2, 0x32, 0x1e, 0x3b, + 0x42, 0x4b, 0xc9, 0xc2, 0x52, 0x5e, 0xc6, 0x52, 0xb0, 0x0e, 0x99, 0xc6, + 0x8f, 0xed, 0x75, 0x6e, 0xa0, 0xdf, 0xd5, 0xc1, 0xa6, 0x8a, 0x2d, 0x4e, + 0xd0, 0xfd, 0xf0, 0xd4, 0xb5, 0x2a, 0x41, 0xf7, 0xc3, 0xaf, 0xa8, 0x3c, + 0x93, 0x4b, 0x1c, 0x76, 0xa0, 0x21, 0x41, 0x0c, 0xb9, 0x2c, 0x15, 0x28, + 0xe5, 0x1f, 0xc6, 0xf2, 0xd5, 0x47, 0x5c, 0xd8, 0x56, 0x5a, 0x76, 0x16, + 0x96, 0x6d, 0xa8, 0x0e, 0x54, 0x26, 0xe2, 0x5b, 0x15, 0xe8, 0x28, 0x54, + 0x50, 0x60, 0x45, 0xf8, 0x54, 0x12, 0x85, 0x6c, 0x76, 0x82, 0x05, 0x1a, + 0xbb, 0x33, 0x41, 0x5b, 0xf8, 0xef, 0x79, 0x56, 0xff, 0xc7, 0x3c, 0x2f, + 0x8e, 0xe6, 0x79, 0xe8, 0xdf, 0xf2, 0xe8, 0x95, 0x3c, 0x77, 0x28, 0xf0, + 0xab, 0x30, 0x8f, 0x75, 0x03, 0xdd, 0x73, 0x41, 0xc3, 0xea, 0x12, 0x59, + 0x9d, 0x14, 0xce, 0x1b, 0x13, 0xf4, 0x7b, 0x3b, 0x4d, 0x4f, 0xd7, 0xef, + 0xfe, 0xf0, 0x88, 0x6a, 0x27, 0xbb, 0xdf, 0x55, 0xcd, 0x34, 0x27, 0xe2, + 0xd3, 0x30, 0x57, 0x5e, 0xde, 0x1c, 0x09, 0x8a, 0xd8, 0x43, 0xd6, 0x0d, + 0x2f, 0x09, 0xb3, 0x25, 0x17, 0xd6, 0xd4, 0x3b, 0xc2, 0xc2, 0x11, 0x74, + 0x93, 0x27, 0x19, 0x71, 0x8f, 0x70, 0xe3, 0x31, 0xb0, 0x3d, 0x63, 0x55, + 0xc5, 0xd6, 0x24, 0xd4, 0xf0, 0x2b, 0x01, 0xce, 0xde, 0x04, 0x30, 0x71, + 0x8c, 0xa4, 0x12, 0x4b, 0xa1, 0xd5, 0x4c, 0x4b, 0xaf, 0xc6, 0x70, 0x55, + 0x6c, 0xec, 0x20, 0x75, 0x6b, 0x13, 0x44, 0x59, 0x0b, 0x4d, 0xc2, 0x24, + 0x56, 0x3b, 0xc4, 0xf9, 0x38, 0xff, 0x22, 0xff, 0x99, 0x28, 0x86, 0x0f, + 0x16, 0x63, 0x9a, 0xbe, 0x11, 0xfa, 0xfb, 0x8b, 0x11, 0x28, 0xce, 0x94, + 0xa8, 0xab, 0x12, 0xf1, 0xf7, 0x27, 0x19, 0x0a, 0x49, 0xcc, 0x37, 0x94, + 0x36, 0xc7, 0xe8, 0xb3, 0x04, 0x96, 0x04, 0x32, 0xcd, 0x2b, 0x66, 0xb6, + 0x0a, 0x4c, 0xf7, 0x1b, 0x72, 0x93, 0xf0, 0xfa, 0x29, 0xb2, 0x87, 0xdd, + 0x9f, 0x88, 0x8f, 0x8c, 0xb8, 0x40, 0x7b, 0x24, 0xd6, 0x49, 0xf7, 0xa6, + 0xab, 0x7c, 0x64, 0x17, 0x2d, 0xf5, 0x9f, 0x4a, 0x1f, 0xd2, 0x31, 0x4b, + 0xd7, 0x5e, 0x7d, 0x83, 0x3b, 0x69, 0xa4, 0xe0, 0x11, 0x98, 0xa0, 0x47, + 0x3c, 0xe4, 0x6c, 0x80, 0x09, 0x6a, 0x49, 0x15, 0x3b, 0x3a, 0x40, 0x21, + 0x7b, 0x70, 0x24, 0x89, 0xbd, 0xee, 0x11, 0x8a, 0x3d, 0x9a, 0x97, 0x8e, + 0x7d, 0xba, 0x9e, 0xc0, 0x1c, 0x4c, 0xc4, 0xc5, 0x11, 0x53, 0x27, 0xa5, + 0xcf, 0xaa, 0x50, 0x4a, 0xc8, 0xd4, 0xb1, 0x3d, 0x04, 0x0c, 0xe7, 0x7d, + 0x2f, 0x94, 0xc9, 0x9a, 0xbc, 0x56, 0x0d, 0x53, 0xa3, 0xf2, 0x66, 0xf9, + 0x13, 0xf1, 0x6d, 0x98, 0x86, 0xd2, 0x71, 0x72, 0x5c, 0x6a, 0x70, 0xdc, + 0x26, 0xe2, 0x29, 0x09, 0x65, 0xed, 0x0e, 0x8e, 0x4e, 0xba, 0x1a, 0x0d, + 0x80, 0x8e, 0x9f, 0x01, 0x07, 0x5d, 0x11, 0xd7, 0x0c, 0x11, 0x3f, 0x5b, + 0xb3, 0xc8, 0xaf, 0x2b, 0xb7, 0xf8, 0xcd, 0xf7, 0xd3, 0xf5, 0x27, 0x34, + 0x2e, 0x1b, 0xc7, 0x5c, 0xda, 0xcb, 0xb1, 0x8e, 0x5d, 0x47, 0xcc, 0x2f, + 0xe8, 0xfe, 0xa4, 0x05, 0x12, 0xf6, 0xd8, 0x9d, 0x40, 0x22, 0xec, 0x7e, + 0xd5, 0x13, 0xda, 0xd8, 0xdf, 0x46, 0xd8, 0xc3, 0x1a, 0x98, 0x51, 0xac, + 0x3f, 0x45, 0x5c, 0x4c, 0x6c, 0x4b, 0x82, 0xc6, 0xac, 0xcd, 0x61, 0x81, + 0xc6, 0x49, 0x23, 0x15, 0x81, 0x72, 0x58, 0x12, 0xa0, 0x2b, 0xc0, 0x5b, + 0x66, 0xb3, 0x87, 0xd4, 0xb0, 0x5b, 0x59, 0x09, 0xc8, 0xc4, 0xd6, 0x27, + 0x8a, 0x21, 0xfb, 0x48, 0xec, 0x35, 0xdd, 0x6b, 0xaa, 0x23, 0xdc, 0x6c, + 0x93, 0xb2, 0x9a, 0x88, 0xc4, 0x0a, 0x06, 0x29, 0x44, 0xae, 0x8e, 0xc6, + 0x02, 0x28, 0x64, 0xab, 0x97, 0xb2, 0x86, 0x80, 0x4f, 0xc1, 0xad, 0xc1, + 0xef, 0xf3, 0xbb, 0x3a, 0x9b, 0x52, 0xe9, 0x38, 0x97, 0x0a, 0x12, 0x7c, + 0x81, 0xc6, 0x16, 0xe0, 0xef, 0x65, 0xab, 0xd3, 0x5d, 0x10, 0x63, 0x12, + 0xb6, 0x00, 0xb1, 0x53, 0xd7, 0x25, 0x6c, 0xeb, 0x1b, 0x48, 0xe3, 0x3a, + 0x6c, 0xab, 0x35, 0x44, 0xb9, 0x00, 0x5d, 0x9b, 0xa7, 0x41, 0x7e, 0x95, + 0x6c, 0x2d, 0xe5, 0x6e, 0xc3, 0x8a, 0xab, 0x3f, 0xfa, 0x67, 0xcb, 0x35, + 0xdf, 0xc1, 0x3b, 0x52, 0xe7, 0xd8, 0xc0, 0xe8, 0x22, 0xb1, 0xd2, 0x61, + 0x88, 0x85, 0x46, 0x28, 0x07, 0xd0, 0x39, 0x58, 0x7b, 0x36, 0x86, 0x98, + 0x30, 0x64, 0xcd, 0xd7, 0x21, 0x05, 0x18, 0xa2, 0x1d, 0xc6, 0x31, 0xbe, + 0x8e, 0xf2, 0x07, 0x0a, 0x0f, 0xf0, 0xe0, 0x88, 0x75, 0x30, 0x7e, 0xaf, + 0x7f, 0xb6, 0x8f, 0x05, 0x6b, 0xe8, 0x87, 0x47, 0xc0, 0x99, 0x22, 0x13, + 0xdb, 0xac, 0x6a, 0x8f, 0x80, 0xed, 0x19, 0xd6, 0x3a, 0xbc, 0x3e, 0x8b, + 0xdf, 0x5b, 0xb3, 0xd8, 0x4f, 0x69, 0xc1, 0x68, 0x63, 0x62, 0x9f, 0x29, + 0x3b, 0x3b, 0x54, 0x98, 0xe3, 0xe6, 0x5b, 0x67, 0xf8, 0xd4, 0xb0, 0xc5, + 0xdf, 0x5b, 0xcf, 0x1c, 0x70, 0x41, 0x4a, 0xec, 0xd9, 0x01, 0x28, 0x76, + 0x8f, 0xf2, 0x14, 0x26, 0x12, 0x16, 0x4a, 0x65, 0xd2, 0x74, 0xc3, 0x6d, + 0xa0, 0xec, 0x94, 0x3a, 0x34, 0x0c, 0xc5, 0xc5, 0x3d, 0xf7, 0xd5, 0x4f, + 0xf6, 0xed, 0xad, 0xf7, 0xaf, 0x78, 0x8b, 0x5b, 0x2c, 0x2c, 0x98, 0x29, + 0xc2, 0x92, 0x45, 0xe0, 0x4c, 0x3f, 0x7d, 0x20, 0x40, 0x62, 0x1d, 0x18, + 0x9f, 0x2f, 0x1d, 0x08, 0xf8, 0x57, 0x90, 0xd8, 0x3b, 0xc3, 0xce, 0x9a, + 0xfa, 0x15, 0xe2, 0x68, 0x9a, 0x0f, 0xe7, 0x8d, 0xbf, 0xc6, 0x77, 0xf7, + 0xa2, 0xd4, 0x5e, 0x5a, 0x57, 0x78, 0x80, 0xf0, 0x24, 0xfc, 0x7e, 0xd4, + 0x3e, 0x5a, 0x3e, 0x5d, 0xb7, 0xf9, 0xfe, 0x69, 0xa4, 0x6a, 0x91, 0xf2, + 0x2c, 0x9a, 0xa2, 0x74, 0x80, 0xee, 0xd0, 0x6b, 0xe4, 0x97, 0x30, 0x4c, + 0xb8, 0x8b, 0xb7, 0xaa, 0xd8, 0xf0, 0x8a, 0x9c, 0x65, 0x2b, 0x7e, 0xb6, + 0xe2, 0x23, 0x62, 0x55, 0x65, 0x79, 0xe9, 0x9e, 0x92, 0x52, 0x50, 0x85, + 0x99, 0x43, 0x14, 0x36, 0x8e, 0xff, 0x8e, 0xd7, 0xe4, 0xfb, 0xca, 0xdc, + 0x7d, 0xbd, 0xdb, 0x9f, 0xee, 0xdb, 0xbb, 0xc2, 0xed, 0x27, 0xfc, 0x16, + 0x4f, 0xdd, 0x8a, 0x8c, 0x40, 0x0a, 0x52, 0xe1, 0x26, 0x1c, 0xc7, 0x14, + 0xdf, 0x73, 0x2b, 0xc1, 0x64, 0xea, 0x85, 0x5e, 0xba, 0xec, 0xe3, 0xed, + 0x4c, 0xb0, 0x7d, 0x77, 0x98, 0x2e, 0x41, 0xb0, 0xcd, 0x43, 0x31, 0xf6, + 0x22, 0xf6, 0xfa, 0x3c, 0x1b, 0x4a, 0x34, 0x4f, 0x2f, 0x95, 0x77, 0x28, + 0xdf, 0x14, 0x7a, 0x25, 0x52, 0x22, 0xbe, 0x6f, 0xe4, 0x9b, 0x1e, 0x54, + 0x7f, 0xed, 0xa2, 0xf8, 0x7f, 0xf6, 0x96, 0xaf, 0x97, 0x30, 0x40, 0x12, + 0x6b, 0x94, 0x17, 0xd2, 0x15, 0xa5, 0xc1, 0xd9, 0xc4, 0x37, 0x18, 0xdd, + 0xad, 0x06, 0xdb, 0x8d, 0x69, 0xf4, 0xec, 0x0d, 0xb0, 0x83, 0x83, 0x51, + 0xc6, 0xb5, 0x65, 0x5d, 0x70, 0x36, 0xed, 0xb7, 0x8d, 0x1d, 0x15, 0x55, + 0xaa, 0x43, 0xcc, 0x41, 0x72, 0x80, 0xc4, 0x86, 0xb1, 0xed, 0xb5, 0x92, + 0x2a, 0xc2, 0xb4, 0x92, 0x16, 0x12, 0xfb, 0xcd, 0xf0, 0x14, 0x1f, 0x71, + 0x4c, 0x99, 0x4b, 0x57, 0xdd, 0x5a, 0x72, 0x4a, 0x83, 0xe0, 0x1c, 0x2b, + 0xbb, 0xa9, 0xcc, 0x93, 0xcb, 0xf1, 0xd7, 0x24, 0x11, 0x7b, 0xcc, 0xa6, + 0x8e, 0x6d, 0xef, 0x63, 0xe1, 0x3a, 0x5f, 0x0c, 0x47, 0x0d, 0xe7, 0x67, + 0x62, 0x7d, 0xc3, 0x13, 0x7d, 0xf5, 0xfe, 0x89, 0xbe, 0x36, 0x7c, 0x2e, + 0xf8, 0x27, 0xa2, 0x24, 0x51, 0x0f, 0x4d, 0xbc, 0x95, 0xae, 0xd0, 0xff, + 0xc7, 0x48, 0x22, 0xfe, 0x54, 0xc2, 0x19, 0xba, 0x0a, 0x37, 0xc4, 0xfa, + 0x86, 0xa8, 0xef, 0x3a, 0xf9, 0x9c, 0xbd, 0x10, 0x65, 0x58, 0x22, 0xfe, + 0x33, 0xc5, 0x3f, 0x5e, 0xb6, 0xcc, 0x81, 0x09, 0x8c, 0x6c, 0xf6, 0xd1, + 0x7d, 0x8a, 0x89, 0x78, 0xc7, 0x08, 0x0d, 0xcd, 0x41, 0x0a, 0xfe, 0x81, + 0xe2, 0x1a, 0x27, 0xd3, 0xd8, 0x4c, 0x9f, 0xb2, 0xa2, 0xda, 0x96, 0x88, + 0x2f, 0x1b, 0x19, 0x87, 0x3a, 0x41, 0x25, 0x96, 0x1e, 0x1a, 0x4a, 0xc4, + 0xbf, 0x85, 0xcf, 0xb2, 0xc4, 0x40, 0x54, 0x53, 0x9d, 0x89, 0x75, 0x3f, + 0x30, 0x32, 0x79, 0xdd, 0xf9, 0x68, 0x22, 0x1e, 0x1e, 0x51, 0x6a, 0xb4, + 0x51, 0x09, 0xb2, 0x55, 0xcb, 0x28, 0x78, 0xba, 0x96, 0xee, 0x29, 0x6e, + 0x42, 0x84, 0x98, 0x16, 0xe2, 0x33, 0x15, 0x1f, 0xda, 0x27, 0x14, 0x37, + 0x74, 0xcc, 0xff, 0x08, 0xfb, 0xaa, 0x0a, 0xfb, 0x67, 0x4b, 0xc3, 0x9b, + 0x0d, 0x61, 0x41, 0x2d, 0x37, 0x3a, 0xbc, 0xcb, 0x9b, 0x81, 0xad, 0xb0, + 0x06, 0x44, 0x8e, 0xcb, 0x0f, 0xce, 0x96, 0xf8, 0x60, 0x47, 0x71, 0x01, + 0xc5, 0xf9, 0x5d, 0xde, 0x0c, 0x5f, 0x8e, 0xf9, 0xf9, 0x86, 0xb6, 0xc0, + 0xd3, 0x82, 0x41, 0x59, 0xe5, 0x7b, 0x29, 0x71, 0xa1, 0x41, 0x83, 0x3e, + 0x56, 0x62, 0x6f, 0x7a, 0xbe, 0xf6, 0x07, 0x57, 0x4c, 0x5b, 0x83, 0x9d, + 0x8d, 0xf6, 0x62, 0xd8, 0x86, 0xe3, 0xfe, 0xe1, 0xe1, 0x46, 0x47, 0xbd, + 0x52, 0x52, 0x7d, 0x9d, 0x35, 0x10, 0xe1, 0x2e, 0xd4, 0x0e, 0xbb, 0x13, + 0x6e, 0x47, 0x5d, 0x5b, 0xed, 0x47, 0xd1, 0xa5, 0x58, 0xaf, 0xc4, 0xc7, + 0x3a, 0x68, 0xa9, 0x3f, 0x3c, 0x42, 0xc2, 0xf4, 0x2c, 0x16, 0x55, 0x78, + 0xdd, 0x2b, 0xf3, 0x7c, 0xc5, 0xb6, 0xdd, 0x95, 0x44, 0x5c, 0xe8, 0xad, + 0xaf, 0xcc, 0xe5, 0x4a, 0x97, 0x1f, 0x6a, 0x60, 0xa7, 0x87, 0xb1, 0x74, + 0x55, 0x84, 0x7d, 0xeb, 0x50, 0x2d, 0x1d, 0x57, 0xcb, 0x97, 0x37, 0x34, + 0x1c, 0x0e, 0x7c, 0xcb, 0xf2, 0x4b, 0x13, 0xfb, 0xe4, 0x67, 0x0d, 0xa2, + 0xf5, 0xfb, 0x79, 0xa2, 0xe9, 0x2b, 0xb2, 0xc7, 0xec, 0x6c, 0xb0, 0x5a, + 0x45, 0xd3, 0x15, 0x6e, 0xe6, 0xad, 0x2f, 0x09, 0x8c, 0xec, 0xa9, 0x62, + 0x63, 0xcf, 0x25, 0x96, 0x56, 0xb2, 0x8b, 0x56, 0x04, 0x4c, 0xd6, 0x46, + 0x13, 0x67, 0x21, 0xc5, 0x39, 0xdd, 0xcc, 0x0d, 0x21, 0xd8, 0x22, 0x4c, + 0x3f, 0xd5, 0x63, 0x5d, 0xa2, 0x13, 0xe1, 0x22, 0x97, 0x95, 0xbb, 0xd8, + 0xf2, 0xac, 0x50, 0x72, 0xca, 0x06, 0xad, 0xc2, 0x04, 0x6c, 0x37, 0x1f, + 0x68, 0x86, 0x8f, 0xfd, 0x22, 0xe7, 0xac, 0x65, 0xc5, 0x95, 0xb5, 0x17, + 0x39, 0x3e, 0xb0, 0xb2, 0xee, 0xe3, 0x5a, 0xf4, 0xd7, 0x15, 0x17, 0x34, + 0xda, 0x88, 0xd8, 0x08, 0x77, 0x79, 0x8b, 0x11, 0x03, 0xcb, 0x96, 0x33, + 0x31, 0x18, 0x0e, 0xfa, 0xdb, 0x1a, 0x54, 0x11, 0x8b, 0xbf, 0x7e, 0xb9, + 0x25, 0x77, 0x79, 0x5d, 0xa3, 0x63, 0x09, 0xe6, 0x8e, 0x70, 0x1f, 0xd7, + 0x96, 0x62, 0x0b, 0x0f, 0x44, 0x5b, 0x85, 0xbf, 0x48, 0xac, 0xc8, 0xe5, + 0x36, 0x5a, 0x6c, 0x5c, 0x4a, 0xec, 0x54, 0xdf, 0xfb, 0xd1, 0x3d, 0xf4, + 0x10, 0x1e, 0xd4, 0x56, 0xbe, 0xe2, 0x1a, 0x79, 0x51, 0xbd, 0x47, 0x20, + 0xc7, 0xd9, 0xd8, 0x6d, 0x89, 0x23, 0x88, 0xa9, 0xd3, 0x43, 0xc5, 0x0e, + 0x22, 0x7e, 0x61, 0x5d, 0x8c, 0x23, 0x6b, 0xa9, 0x0e, 0xc7, 0xef, 0xf2, + 0x45, 0x0d, 0xcf, 0x01, 0x5b, 0xae, 0x6e, 0x62, 0xcd, 0x3b, 0x15, 0xe9, + 0x3a, 0xdf, 0x92, 0x12, 0xfb, 0x65, 0x5f, 0x31, 0x4f, 0x22, 0x8b, 0xbd, + 0x5a, 0x1f, 0xd3, 0xfc, 0x0c, 0xf7, 0x70, 0xa0, 0x15, 0xd4, 0x3e, 0x69, + 0x21, 0x13, 0xfb, 0xfd, 0x90, 0xca, 0xc7, 0x44, 0xd4, 0xad, 0xdf, 0xf7, + 0xcb, 0xf3, 0x76, 0xe3, 0xf8, 0xa3, 0xb8, 0xc5, 0x71, 0x97, 0xff, 0x28, + 0xf6, 0x69, 0x5f, 0x47, 0xe3, 0x78, 0x6e, 0xce, 0xeb, 0x00, 0x85, 0x3a, + 0xbe, 0xd0, 0x5f, 0xef, 0x7f, 0xde, 0x7f, 0xc9, 0x5f, 0x58, 0x7b, 0x6f, + 0xed, 0xf3, 0xb5, 0x97, 0x6a, 0x0b, 0xeb, 0xee, 0xad, 0xb3, 0x21, 0x97, + 0x12, 0x87, 0xea, 0x03, 0x36, 0x3f, 0xa9, 0xa0, 0x38, 0xf9, 0x1d, 0x37, + 0x15, 0xe1, 0x69, 0x1e, 0x42, 0x08, 0xe1, 0x2d, 0x8e, 0xaf, 0xe5, 0xeb, + 0x0c, 0xbe, 0x65, 0xb5, 0xbd, 0xfe, 0x65, 0x75, 0xbd, 0xb5, 0x7b, 0xfd, + 0x7b, 0x6b, 0x8b, 0x27, 0xbb, 0xfc, 0x6d, 0xc2, 0x5f, 0x65, 0xb5, 0xcf, + 0x92, 0x9b, 0xbb, 0xf6, 0x69, 0xff, 0xdd, 0xb5, 0xa7, 0xfd, 0x96, 0xda, + 0xbe, 0x4e, 0x5a, 0x27, 0x95, 0x59, 0x73, 0xf0, 0x61, 0x71, 0x3c, 0x73, + 0x01, 0x88, 0x59, 0x87, 0x06, 0x70, 0x34, 0x36, 0x02, 0x1d, 0xbf, 0xb3, + 0x14, 0xbd, 0x4d, 0x33, 0x07, 0xec, 0x36, 0xe4, 0x37, 0xa8, 0xdf, 0x16, + 0xb3, 0x12, 0x13, 0x9b, 0x83, 0x9a, 0x82, 0x21, 0xf6, 0x31, 0x6a, 0x8d, + 0x34, 0xef, 0x0c, 0xaa, 0xeb, 0xf9, 0x54, 0x35, 0x2a, 0xa4, 0xeb, 0x7f, + 0x0e, 0xa1, 0x3e, 0x80, 0xf0, 0xbf, 0x8f, 0x8f, 0x7a, 0x04, 0x4c, 0xae, + 0x0e, 0x7e, 0x0e, 0xef, 0x2b, 0x98, 0x5b, 0x50, 0x5d, 0x58, 0x53, 0x58, + 0x05, 0x13, 0x74, 0x12, 0x38, 0x75, 0x32, 0x4c, 0xcc, 0x94, 0xa1, 0x24, + 0x4d, 0x86, 0x52, 0xa3, 0xec, 0xea, 0x44, 0xad, 0x55, 0x7a, 0xeb, 0xbb, + 0x8f, 0x7e, 0xd7, 0xca, 0xf0, 0xde, 0xc6, 0x82, 0x02, 0x26, 0xc7, 0x5b, + 0x60, 0xd8, 0xb2, 0xee, 0xed, 0x75, 0x30, 0xf1, 0xda, 0xf0, 0x8b, 0xe4, + 0xeb, 0xf0, 0x12, 0x1a, 0xbe, 0x09, 0xc3, 0x53, 0xbc, 0x8d, 0xf6, 0x6a, + 0x30, 0x7b, 0xf5, 0x18, 0xfe, 0xc6, 0x3a, 0xba, 0xcb, 0xe0, 0xad, 0xef, + 0x6e, 0xc6, 0x70, 0x65, 0xef, 0x1b, 0xb1, 0x78, 0x33, 0x31, 0xfc, 0xcd, + 0x75, 0xc0, 0xab, 0xd6, 0x7a, 0xd7, 0x6e, 0x59, 0x7b, 0x14, 0x71, 0xdc, + 0x70, 0x0d, 0x3f, 0xba, 0xfa, 0xf7, 0x36, 0x4b, 0xf5, 0x97, 0x1f, 0xcd, + 0xe9, 0x3c, 0x62, 0x87, 0xdb, 0x1c, 0xd9, 0xfb, 0x99, 0xd8, 0x87, 0x83, + 0x76, 0xf0, 0x3a, 0x6e, 0x2b, 0x53, 0xa1, 0xfb, 0xfc, 0xe0, 0x0f, 0xe7, + 0x14, 0xe5, 0x81, 0xe4, 0x2d, 0xfa, 0x81, 0xef, 0x87, 0xb7, 0xd1, 0xb1, + 0xfd, 0x03, 0xdf, 0x6d, 0xd7, 0xd3, 0x15, 0xd4, 0x53, 0x40, 0xdd, 0xbb, + 0x85, 0x6a, 0xe3, 0xf2, 0x3f, 0x7a, 0xa7, 0xc0, 0xac, 0x29, 0xc5, 0xa0, + 0x8e, 0xb1, 0x7d, 0xa4, 0x69, 0xaa, 0x9f, 0xee, 0x99, 0xfa, 0xb8, 0xf7, + 0x7b, 0xbe, 0x5c, 0x3f, 0x4c, 0x50, 0x49, 0x5e, 0x87, 0xea, 0x00, 0x13, + 0xfb, 0xed, 0xe0, 0x83, 0x3e, 0xba, 0x9a, 0x13, 0x26, 0x80, 0xfc, 0x41, + 0xef, 0x43, 0xd5, 0xb7, 0x39, 0x32, 0xcb, 0x8a, 0xb1, 0xfc, 0xf6, 0xc1, + 0xdb, 0x1c, 0xa4, 0xa5, 0xf8, 0x80, 0x17, 0x25, 0xf3, 0xe1, 0xc1, 0x35, + 0x4a, 0x79, 0x7f, 0xea, 0xad, 0xcf, 0xdb, 0x3d, 0x73, 0xb9, 0x0f, 0xec, + 0x8b, 0xf3, 0xc2, 0x33, 0xcb, 0xf7, 0x67, 0x39, 0xc8, 0xe4, 0x8b, 0x1c, + 0x13, 0x7b, 0x72, 0xf0, 0x59, 0x1b, 0xe1, 0x8b, 0x5f, 0x28, 0x5e, 0x9b, + 0x33, 0x75, 0xff, 0xda, 0x3b, 0xa7, 0x7e, 0xb8, 0xae, 0x8b, 0x0b, 0xac, + 0xef, 0xe2, 0x3e, 0x5c, 0xef, 0xb6, 0x7d, 0xb2, 0x76, 0x4a, 0x81, 0xde, + 0xa1, 0xb6, 0x6f, 0x1a, 0xff, 0xe1, 0xfd, 0x18, 0xfa, 0x40, 0xfe, 0xd4, + 0xfd, 0x0f, 0x98, 0x5c, 0xc5, 0x0f, 0x2e, 0x76, 0x05, 0x1e, 0x1c, 0xeb, + 0xda, 0xff, 0xe0, 0x4f, 0xa6, 0x7e, 0xf8, 0xe0, 0x1a, 0x57, 0xf1, 0x43, + 0xab, 0xa6, 0x06, 0x1e, 0xd2, 0x4c, 0x7d, 0xb4, 0x72, 0xe5, 0xfd, 0x1f, + 0x3e, 0xc4, 0x1c, 0x7e, 0xca, 0x05, 0xe6, 0x92, 0xe0, 0x8a, 0xe0, 0xc1, + 0xe0, 0xdf, 0x83, 0x2b, 0xd6, 0x96, 0xac, 0x5b, 0xb1, 0xee, 0xe0, 0xba, + 0xd2, 0xf5, 0x07, 0xd7, 0x97, 0xde, 0x7f, 0xf0, 0xfe, 0xd2, 0x07, 0xfe, + 0xf1, 0xc0, 0x8b, 0x0f, 0xbd, 0xf1, 0x50, 0xc4, 0x06, 0xe6, 0xb7, 0x1e, + 0x12, 0xf1, 0x77, 0x5a, 0xc1, 0x9b, 0x0f, 0x95, 0xec, 0x7f, 0xfb, 0xa1, + 0xa7, 0x6d, 0xcc, 0x61, 0x30, 0x8f, 0x29, 0x78, 0xfb, 0xa1, 0x3d, 0x8a, + 0xeb, 0xad, 0x87, 0x9e, 0xc1, 0xd8, 0x42, 0xf4, 0x97, 0xee, 0xcf, 0xbd, + 0xf1, 0xed, 0x87, 0x98, 0xfd, 0xbf, 0x9a, 0x0c, 0xe6, 0x1d, 0x37, 0xb2, + 0xc1, 0x37, 0x95, 0xf8, 0xca, 0x02, 0x36, 0xf8, 0x96, 0xe2, 0xaa, 0x40, + 0x97, 0x7b, 0xbf, 0x2a, 0xf8, 0x8e, 0xe2, 0x7b, 0x02, 0x7d, 0xbf, 0x53, + 0x5c, 0xaa, 0xe0, 0xef, 0xb1, 0x84, 0x07, 0xd0, 0x3f, 0x79, 0xff, 0x2a, + 0xcc, 0x77, 0x54, 0x09, 0xd5, 0x06, 0xff, 0x80, 0xa1, 0xc8, 0x0d, 0x82, + 0xef, 0x29, 0x7e, 0x12, 0x9c, 0x72, 0xc0, 0x10, 0x34, 0xdb, 0xdf, 0x2e, + 0xcf, 0x34, 0x67, 0x04, 0xff, 0xec, 0xc8, 0x34, 0x67, 0x05, 0xdf, 0x77, + 0x94, 0xd8, 0xa9, 0xcf, 0xe6, 0xb8, 0x1e, 0xe3, 0x64, 0xbb, 0x1e, 0xe1, + 0x32, 0x06, 0x8f, 0xdb, 0x99, 0xfd, 0x7a, 0xce, 0x34, 0xd9, 0x18, 0xbc, + 0xe1, 0x40, 0x4a, 0xf0, 0xa4, 0xe2, 0x0b, 0xa2, 0xef, 0x2f, 0x8a, 0xcb, + 0x10, 0xfc, 0x65, 0x79, 0x26, 0x67, 0xbb, 0x31, 0x3b, 0x38, 0xf5, 0x60, + 0x56, 0xb0, 0xdb, 0x6d, 0x45, 0x76, 0x79, 0x9a, 0xaf, 0xab, 0xb4, 0x72, + 0x96, 0x60, 0x0f, 0xdf, 0xe5, 0xa0, 0x6f, 0x7a, 0xae, 0x54, 0x8b, 0xf9, + 0x91, 0xe9, 0x4c, 0xec, 0xdc, 0x80, 0xba, 0x17, 0x26, 0x81, 0xa4, 0x89, + 0xea, 0x7d, 0x37, 0xfb, 0xf3, 0xfc, 0x37, 0x21, 0x37, 0xa3, 0x7d, 0x96, + 0x7d, 0xa0, 0x30, 0xfa, 0xd8, 0xc8, 0x37, 0xf4, 0x34, 0x35, 0x2d, 0xc9, + 0xb7, 0xab, 0xf0, 0xad, 0x4e, 0x80, 0x89, 0x28, 0x52, 0xae, 0xab, 0x92, + 0x86, 0x5f, 0x75, 0x7b, 0x14, 0x5d, 0xf9, 0x4d, 0xdf, 0xaf, 0x8f, 0x50, + 0x49, 0x08, 0xd2, 0x7d, 0xe7, 0xba, 0x7c, 0x5d, 0xb7, 0x52, 0xd7, 0x9a, + 0x73, 0xaf, 0x2b, 0x96, 0xdd, 0x8a, 0x73, 0xbf, 0x9d, 0x0b, 0x13, 0x41, + 0x5a, 0x79, 0x8e, 0x41, 0xe9, 0xef, 0x04, 0x98, 0xa4, 0x96, 0x51, 0x5f, + 0xee, 0x45, 0x5f, 0x21, 0xf5, 0x93, 0x88, 0xc8, 0xfd, 0xb2, 0xa6, 0xa7, + 0x1d, 0xe5, 0x3a, 0x8f, 0xe2, 0x5d, 0x39, 0xd5, 0xe4, 0xe5, 0xea, 0xe3, + 0x5c, 0x4f, 0xbb, 0xe0, 0xa8, 0x2d, 0x33, 0xed, 0x67, 0xc2, 0x4c, 0x6c, + 0xeb, 0xc0, 0x11, 0x9f, 0xfe, 0xb0, 0x35, 0x60, 0x76, 0xd0, 0x71, 0x4b, + 0x4f, 0xc6, 0xda, 0x30, 0x70, 0x17, 0xba, 0xed, 0x48, 0x6f, 0xf7, 0x0f, + 0xf8, 0xc6, 0x63, 0x6b, 0x64, 0x61, 0x86, 0x99, 0x5f, 0x2e, 0x64, 0x79, + 0x9e, 0xab, 0x49, 0x70, 0x77, 0x8d, 0x96, 0x94, 0xe0, 0xf4, 0x98, 0x4a, + 0x83, 0xa9, 0x6a, 0x07, 0x06, 0xdb, 0xa7, 0x82, 0x3a, 0xcc, 0xc6, 0xc4, + 0x91, 0x27, 0x7d, 0x9a, 0x3c, 0xce, 0x0f, 0x72, 0xc6, 0xb9, 0xe9, 0x00, + 0x76, 0x26, 0xb6, 0x60, 0x40, 0xef, 0xd0, 0x1c, 0xb2, 0x04, 0x19, 0x5e, + 0x73, 0x70, 0x41, 0x30, 0x0b, 0xd4, 0x11, 0x17, 0x44, 0x82, 0x4c, 0x44, + 0x73, 0xc0, 0xb2, 0x96, 0xd0, 0xb0, 0xb5, 0xcf, 0xb8, 0x8f, 0xaf, 0xe5, + 0x2b, 0xb2, 0xd6, 0xe9, 0x1d, 0x4c, 0x4c, 0x18, 0x70, 0xc1, 0x56, 0x9f, + 0xde, 0x45, 0xdb, 0xf6, 0x55, 0x2f, 0xd3, 0x04, 0x13, 0x4b, 0x24, 0x96, + 0xaf, 0x47, 0xfc, 0xea, 0xed, 0x6d, 0x41, 0x6a, 0x8b, 0xf1, 0xeb, 0xdb, + 0xd6, 0xdb, 0xdd, 0x17, 0xd6, 0xb3, 0xa2, 0xca, 0xc1, 0xdf, 0x6f, 0xcd, + 0xac, 0xbf, 0x5f, 0xcb, 0xb7, 0xdd, 0xcf, 0x54, 0x5c, 0xb8, 0xff, 0xfb, + 0x6e, 0x7b, 0xb0, 0x76, 0x1d, 0xff, 0x00, 0x57, 0xe6, 0xad, 0x78, 0x76, + 0x5d, 0xdb, 0x03, 0xa6, 0x69, 0xd7, 0x57, 0xd4, 0xad, 0x3d, 0xb7, 0xae, + 0xee, 0x01, 0xfe, 0x41, 0x3b, 0x30, 0x2d, 0x63, 0xcb, 0x99, 0x58, 0xe6, + 0x00, 0x23, 0x9a, 0xdd, 0x4c, 0x78, 0x9d, 0x32, 0x72, 0x5e, 0xef, 0x65, + 0x0b, 0x55, 0xe3, 0x57, 0x15, 0xd8, 0x0f, 0xcc, 0x0d, 0xc2, 0x13, 0x7f, + 0xba, 0x3f, 0xfd, 0xc1, 0x8d, 0x66, 0xcd, 0x0b, 0x4b, 0xcd, 0xef, 0x3f, + 0x38, 0x1e, 0x0a, 0x0b, 0x86, 0x1e, 0xd2, 0x8c, 0x2f, 0x28, 0x52, 0x89, + 0x35, 0x93, 0x97, 0x9a, 0xa3, 0x0f, 0x2d, 0xce, 0x71, 0x1c, 0xbe, 0xfc, + 0xd0, 0xb1, 0xf6, 0xb5, 0x05, 0x35, 0xf7, 0x1b, 0x1e, 0x60, 0x1c, 0x2a, + 0x71, 0xa9, 0xf9, 0xfc, 0x43, 0xeb, 0x0a, 0x76, 0x20, 0x54, 0x4b, 0xcd, + 0x17, 0x1e, 0x5a, 0x5f, 0x40, 0x7f, 0x9d, 0x87, 0xc7, 0x07, 0x9f, 0x40, + 0xd7, 0x78, 0x98, 0x0c, 0x7a, 0xdb, 0x3a, 0xcc, 0xa9, 0x0b, 0xfa, 0xd6, + 0xee, 0x58, 0x5b, 0xb5, 0xee, 0xc7, 0xeb, 0xde, 0x5b, 0xe7, 0x5b, 0xbf, + 0x75, 0x7d, 0xca, 0xfd, 0x5b, 0xef, 0xdf, 0xfe, 0xc0, 0x7b, 0x0f, 0xa4, + 0x3d, 0xe4, 0x7b, 0xe8, 0xbd, 0x87, 0x6e, 0x0e, 0x3a, 0x82, 0x4f, 0x61, + 0x7a, 0x47, 0x30, 0x82, 0xbf, 0xb6, 0xa0, 0x58, 0x30, 0xe1, 0xc5, 0xa5, + 0xe6, 0xe9, 0xc1, 0xf1, 0x50, 0x50, 0x70, 0x63, 0xf0, 0x69, 0x0c, 0xe3, + 0x83, 0x7b, 0x0a, 0x54, 0x45, 0x4b, 0xcd, 0x45, 0xc1, 0x67, 0x14, 0xdf, + 0xb3, 0xca, 0x6f, 0x9b, 0x92, 0xba, 0xa0, 0x60, 0xe2, 0x8b, 0x37, 0x07, + 0x27, 0xbd, 0x38, 0x3d, 0x78, 0xdd, 0x8b, 0x37, 0x06, 0x37, 0x4d, 0xa6, + 0xa9, 0x7e, 0xaa, 0x94, 0xf6, 0xb3, 0x02, 0x76, 0x3c, 0x42, 0x11, 0x74, + 0x1d, 0xe6, 0x83, 0x07, 0x94, 0x1c, 0x07, 0x95, 0xdf, 0xb2, 0xc3, 0xb6, + 0xa0, 0xba, 0xe0, 0xc0, 0x0d, 0x1b, 0xcd, 0x37, 0x06, 0x7f, 0x3e, 0x7e, + 0xa3, 0xb9, 0x22, 0xf8, 0x22, 0xfe, 0x7a, 0x0a, 0xa7, 0x07, 0xcb, 0x5f, + 0xbc, 0x29, 0xd8, 0x31, 0x5e, 0xf3, 0x02, 0x8d, 0x79, 0x05, 0xc3, 0x6e, + 0x82, 0xc2, 0xf1, 0xd7, 0x05, 0x35, 0x2f, 0x34, 0xdf, 0x40, 0x53, 0xfd, + 0x7a, 0xfc, 0xe4, 0x17, 0x9c, 0x41, 0x1a, 0x5b, 0x11, 0xfc, 0x8d, 0x92, + 0x6a, 0x2a, 0xfa, 0xda, 0x5d, 0x1e, 0xf3, 0xa6, 0x42, 0x36, 0x38, 0x65, + 0xbf, 0x3a, 0xd8, 0x69, 0xd3, 0xbc, 0xe0, 0x31, 0x33, 0x41, 0x8f, 0xed, + 0xb5, 0xf2, 0xf9, 0x66, 0x53, 0xf0, 0x2d, 0x47, 0xe1, 0xf8, 0xf9, 0xe6, + 0xec, 0xe0, 0x0d, 0x07, 0xc7, 0x05, 0xdf, 0x71, 0xcc, 0xc7, 0xb1, 0xf7, + 0xbb, 0xe4, 0xaf, 0x7b, 0x89, 0xf9, 0x2e, 0x07, 0xd3, 0x92, 0x17, 0x64, + 0x62, 0xbe, 0xfe, 0x69, 0xca, 0xf9, 0x5d, 0x68, 0xa7, 0x15, 0xee, 0xbf, + 0x2c, 0x38, 0x4c, 0x07, 0x7c, 0xd7, 0x33, 0x31, 0x4f, 0x3f, 0xf3, 0x24, + 0x13, 0xa5, 0x63, 0x48, 0xbc, 0x4c, 0x9e, 0xfc, 0x27, 0xba, 0x3e, 0x95, + 0x49, 0x61, 0xf8, 0x72, 0x72, 0x3c, 0xd0, 0x31, 0xf3, 0xef, 0x7c, 0x99, + 0x8e, 0x9f, 0x2a, 0x45, 0xf6, 0xb0, 0x90, 0x5d, 0x45, 0xd7, 0x94, 0x33, + 0x72, 0x86, 0x9d, 0xc4, 0xc4, 0x3e, 0x98, 0x60, 0x94, 0x33, 0x7c, 0x19, + 0x35, 0x8b, 0x1b, 0x09, 0x8e, 0x54, 0xe2, 0xee, 0x69, 0x4f, 0xad, 0x5a, + 0x02, 0xcd, 0x90, 0xe5, 0x55, 0x35, 0xa2, 0x65, 0x62, 0x63, 0x27, 0x0c, + 0x76, 0x33, 0x60, 0xf0, 0x3d, 0x07, 0x17, 0x17, 0x6a, 0xab, 0xf7, 0xde, + 0x75, 0xbc, 0x1d, 0x8a, 0x3f, 0x92, 0x48, 0x79, 0x55, 0x23, 0x53, 0x96, + 0x55, 0xfa, 0x15, 0x52, 0xf9, 0x05, 0x94, 0x03, 0x9d, 0xa8, 0x63, 0xed, + 0xc2, 0x47, 0xcf, 0x02, 0xec, 0xc7, 0xba, 0x62, 0x1d, 0x8f, 0x1d, 0x51, + 0xc5, 0xee, 0x1e, 0x54, 0xe7, 0x4d, 0x44, 0x7d, 0xae, 0x0f, 0x75, 0xb5, + 0x09, 0x23, 0x63, 0xaa, 0x20, 0x76, 0x65, 0x44, 0x15, 0x9b, 0x3b, 0x48, + 0x6c, 0x10, 0xfb, 0x4b, 0x7f, 0xe6, 0x9c, 0xac, 0x6a, 0x9b, 0x1f, 0x10, + 0x06, 0x62, 0xb7, 0xa1, 0x9c, 0xdc, 0xd8, 0x07, 0xb1, 0xa7, 0x06, 0xb1, + 0x80, 0x18, 0x37, 0xac, 0x81, 0xf4, 0x3c, 0x72, 0x3a, 0x11, 0xdf, 0x30, + 0x84, 0x56, 0x1a, 0xdf, 0x0c, 0xcd, 0xe6, 0x87, 0x67, 0x82, 0xf3, 0xab, + 0x1e, 0x7a, 0xae, 0x89, 0xa6, 0xda, 0x06, 0xe4, 0x09, 0xd8, 0x09, 0xb1, + 0x47, 0x07, 0xe9, 0xfa, 0x6b, 0x2a, 0x33, 0xa9, 0x5c, 0x9d, 0x36, 0x07, + 0x4c, 0x76, 0x7c, 0xa8, 0xc5, 0x48, 0xf5, 0xe9, 0xff, 0xbb, 0xfb, 0x9d, + 0xfe, 0xc2, 0xd2, 0x3d, 0x0d, 0xac, 0x8f, 0x00, 0x84, 0x39, 0x47, 0x3e, + 0xcf, 0x54, 0xa9, 0x62, 0xf5, 0x23, 0x69, 0x9d, 0xaf, 0x61, 0x7b, 0xa6, + 0x66, 0x63, 0x9c, 0xcf, 0xe4, 0x12, 0x03, 0x8d, 0xf0, 0xc6, 0x3c, 0x5a, + 0x26, 0x7d, 0xa8, 0x95, 0x6b, 0xf6, 0x6f, 0xa6, 0xda, 0xde, 0xec, 0xe4, + 0x39, 0x82, 0x05, 0x58, 0x36, 0x71, 0x6c, 0xf6, 0xa8, 0x7c, 0xd6, 0x40, + 0x96, 0x87, 0x4a, 0x9b, 0xee, 0x76, 0x25, 0xee, 0x1c, 0xea, 0xa5, 0x25, + 0xa8, 0xbf, 0xa1, 0x46, 0x4e, 0x9f, 0xe0, 0x6c, 0x15, 0x6a, 0xeb, 0x5d, + 0x95, 0x8d, 0xe7, 0x31, 0x1c, 0xe3, 0x1a, 0xf1, 0xa1, 0xf6, 0x03, 0x6a, + 0x0c, 0xa8, 0x4d, 0x7e, 0x94, 0xa0, 0x36, 0x21, 0xf5, 0x93, 0x9a, 0x2c, + 0x65, 0x1f, 0x12, 0x60, 0x3a, 0x66, 0xb4, 0xfe, 0xae, 0x85, 0xd8, 0x3a, + 0xac, 0x8b, 0xee, 0x15, 0x4a, 0x05, 0xd4, 0x18, 0x7f, 0xb0, 0xee, 0x15, + 0x43, 0x4d, 0x16, 0xf2, 0xbf, 0x21, 0x89, 0x42, 0x45, 0xf5, 0xd1, 0xbf, + 0x27, 0xb4, 0xbe, 0x16, 0xd4, 0x98, 0xf6, 0x0b, 0xd4, 0xc6, 0x1c, 0xea, + 0x2b, 0x87, 0x12, 0x65, 0x57, 0xd6, 0xd3, 0x89, 0x60, 0x27, 0x85, 0x91, + 0xce, 0xff, 0xd1, 0x3e, 0x52, 0x03, 0xd9, 0x49, 0x75, 0x4e, 0x1c, 0xef, + 0xaf, 0x54, 0x5f, 0x53, 0xc6, 0x75, 0x30, 0xdb, 0x67, 0xba, 0x41, 0x0c, + 0xfc, 0x06, 0x4e, 0x2c, 0xbc, 0xc5, 0xb7, 0x5b, 0x08, 0x48, 0x24, 0xb2, + 0x4b, 0x00, 0xf9, 0x7b, 0xbd, 0x5e, 0xdf, 0x05, 0xcb, 0x75, 0x4e, 0x7f, + 0x37, 0x9d, 0x4b, 0xd9, 0x9e, 0x40, 0x0c, 0x28, 0x3b, 0x65, 0x9f, 0x4d, + 0xd0, 0x5c, 0x23, 0xf1, 0xe2, 0x11, 0x4d, 0x9e, 0x4a, 0xfa, 0xa1, 0x52, + 0xeb, 0x1b, 0x7d, 0x84, 0x77, 0x40, 0xc4, 0x9b, 0x05, 0xe0, 0x98, 0x72, + 0x5b, 0x4b, 0x40, 0x63, 0x7f, 0xb4, 0x92, 0xb4, 0x2c, 0xfa, 0xd6, 0xa3, + 0xb7, 0x64, 0xa3, 0xb6, 0x62, 0x3e, 0x0d, 0x93, 0xaa, 0x51, 0x63, 0xb9, + 0x45, 0x4a, 0xd8, 0x77, 0xae, 0x9d, 0x54, 0xbd, 0xb3, 0x71, 0x52, 0xf5, + 0x84, 0x2a, 0x43, 0x28, 0xb2, 0x76, 0x62, 0x8d, 0xd5, 0xb2, 0x64, 0xe6, + 0x62, 0x6f, 0x66, 0xaa, 0x21, 0x58, 0x8c, 0x58, 0x2b, 0xea, 0x31, 0x3a, + 0x6e, 0xf7, 0x5a, 0xe0, 0x61, 0xee, 0x4c, 0xd4, 0x68, 0xab, 0xf2, 0x3a, + 0x6a, 0xc6, 0x72, 0xbf, 0x0c, 0x3c, 0xe3, 0x8f, 0x6f, 0xf8, 0x60, 0xad, + 0x66, 0x7c, 0xfc, 0xdb, 0xcf, 0xac, 0xfd, 0xe5, 0x86, 0x8d, 0xd7, 0xe5, + 0x75, 0xbf, 0xb2, 0xf5, 0x98, 0xe5, 0x41, 0xf5, 0xf5, 0x63, 0x1a, 0xcd, + 0x99, 0x5c, 0xaf, 0x2d, 0x53, 0x3d, 0x3f, 0x15, 0x18, 0xc6, 0x1b, 0x69, + 0x34, 0x3a, 0x6a, 0xbc, 0x63, 0x7c, 0x22, 0x37, 0x16, 0xfb, 0x3c, 0x23, + 0xd8, 0xb2, 0xb6, 0x18, 0x54, 0xad, 0x89, 0x78, 0x55, 0xc2, 0x8e, 0x6a, + 0x05, 0x13, 0x49, 0xc4, 0xb3, 0x94, 0x55, 0xfc, 0x9d, 0x8e, 0x4c, 0xe6, + 0xc3, 0xa8, 0x61, 0xce, 0xab, 0xd1, 0xb4, 0x9a, 0xf4, 0xea, 0x63, 0x16, + 0xdd, 0xf4, 0x79, 0x8c, 0x27, 0x95, 0x78, 0x5b, 0x1b, 0x8d, 0xd5, 0xf3, + 0x75, 0x06, 0xef, 0xe9, 0xc6, 0xf3, 0xd1, 0x1c, 0xb8, 0x88, 0x7d, 0x46, + 0xf1, 0x47, 0xf1, 0x4f, 0x71, 0xd8, 0x8d, 0x34, 0x03, 0x9d, 0x89, 0x44, + 0x71, 0x0e, 0xd8, 0x0e, 0x1e, 0x04, 0xc8, 0xa4, 0x1b, 0x0f, 0x63, 0x68, + 0xec, 0xf5, 0x25, 0x12, 0x84, 0x8f, 0x77, 0xa8, 0xbc, 0x2c, 0x90, 0xf0, + 0x48, 0x7c, 0xf7, 0x30, 0x62, 0xf9, 0x87, 0xeb, 0x5e, 0xc9, 0xf5, 0x51, + 0x39, 0x35, 0xa8, 0xe0, 0xd8, 0x5a, 0xed, 0x00, 0xab, 0x6f, 0xbe, 0x65, + 0xfe, 0xcc, 0x05, 0x5e, 0x6b, 0xea, 0x92, 0xf6, 0xdd, 0x95, 0x66, 0x5f, + 0x24, 0xb0, 0x05, 0x8e, 0x2d, 0xd4, 0xc1, 0x18, 0x1c, 0xdc, 0xe4, 0x69, + 0x70, 0xfc, 0x5c, 0xc8, 0x96, 0xb3, 0x6a, 0xb2, 0xab, 0x9b, 0x03, 0xf2, + 0xbc, 0x2c, 0x9f, 0x25, 0xb4, 0x6f, 0x6d, 0x5d, 0xa5, 0x25, 0xa8, 0xd0, + 0x1e, 0x8f, 0x7d, 0xee, 0xff, 0x21, 0xd2, 0x5e, 0xbc, 0x93, 0x94, 0x1b, + 0x5d, 0x6c, 0xe9, 0x67, 0x92, 0x86, 0x7f, 0xeb, 0x5b, 0xf5, 0xb7, 0xc4, + 0x65, 0x23, 0xbf, 0xd8, 0x7b, 0xc5, 0xbd, 0x8d, 0xdb, 0xb1, 0x56, 0xeb, + 0xdb, 0x81, 0x70, 0x27, 0x61, 0xa6, 0xb0, 0x52, 0x18, 0xaf, 0xc2, 0x4e, + 0x61, 0xa6, 0xb0, 0xff, 0x9f, 0xec, 0x1d, 0x94, 0x78, 0xad, 0x62, 0xa3, + 0x10, 0xd0, 0x54, 0x81, 0xa3, 0x8b, 0x43, 0xab, 0x34, 0xac, 0xe6, 0x55, + 0xb1, 0xe3, 0x43, 0x74, 0x8f, 0x77, 0x3e, 0xcf, 0x59, 0xd2, 0x3a, 0xcb, + 0xb1, 0xbc, 0xbf, 0x26, 0xa8, 0x8e, 0xaa, 0x9b, 0x4b, 0x1c, 0x2b, 0x97, + 0x03, 0xff, 0xac, 0xa0, 0xe9, 0x7e, 0x61, 0x79, 0x16, 0x3c, 0x26, 0x30, + 0xc7, 0x52, 0xac, 0x8b, 0xf2, 0x76, 0xcc, 0xcc, 0xf2, 0x70, 0x40, 0xe7, + 0xde, 0xc0, 0xa3, 0xf6, 0x6c, 0x09, 0xd0, 0xd3, 0x1e, 0xf5, 0x5c, 0x26, + 0x97, 0x49, 0xf4, 0x64, 0x11, 0x27, 0x72, 0x77, 0x05, 0x6a, 0x02, 0xc4, + 0xb6, 0x4b, 0x50, 0x77, 0xab, 0x64, 0x4b, 0x20, 0x25, 0x40, 0xcf, 0xe6, + 0x01, 0x5b, 0x57, 0xbb, 0x09, 0xa1, 0x4c, 0xa4, 0x07, 0x95, 0x33, 0xd9, + 0x74, 0x74, 0xd6, 0x14, 0x15, 0x6a, 0x88, 0xbd, 0x33, 0x68, 0x03, 0x4d, + 0x35, 0xc4, 0xcc, 0x83, 0x89, 0xf8, 0xb8, 0x11, 0xb5, 0x6f, 0xc2, 0x03, + 0x5d, 0x1c, 0xeb, 0x6b, 0x84, 0xe7, 0x20, 0xe0, 0xbf, 0x34, 0x2f, 0xd8, + 0x79, 0x74, 0x21, 0x98, 0x3c, 0x00, 0x93, 0x57, 0x72, 0x60, 0x33, 0xa0, + 0xbe, 0x80, 0x3d, 0xb0, 0x79, 0xdd, 0x2b, 0x84, 0xee, 0x0a, 0x4c, 0xe2, + 0x3f, 0x90, 0x1c, 0xc3, 0xc9, 0x11, 0xec, 0x79, 0x9d, 0xda, 0xcc, 0x74, + 0xac, 0x35, 0x22, 0x1f, 0x53, 0xf1, 0xae, 0x8e, 0x1c, 0x58, 0xe0, 0x9d, + 0xe3, 0x55, 0x55, 0xbc, 0xc5, 0xa9, 0x6e, 0x6c, 0x0d, 0x92, 0xbb, 0xd5, + 0x66, 0x28, 0x21, 0x72, 0x69, 0xd0, 0xd5, 0xb9, 0x28, 0x38, 0xa8, 0xec, + 0x1d, 0x7f, 0xec, 0x08, 0x13, 0x36, 0x1e, 0xca, 0x09, 0xa5, 0x1e, 0xb2, + 0x86, 0xb4, 0xa0, 0x0e, 0x90, 0x66, 0x55, 0x18, 0x26, 0x98, 0xe4, 0xc3, + 0x0f, 0xc3, 0x84, 0xd9, 0x92, 0x8a, 0xaf, 0xf7, 0x96, 0x06, 0x54, 0x15, + 0xc7, 0xb9, 0xc5, 0xa1, 0x83, 0xeb, 0xa9, 0x46, 0xf0, 0xd1, 0x7a, 0x70, + 0x44, 0x82, 0x8b, 0x83, 0x96, 0xa0, 0xdd, 0xf7, 0x9b, 0xc0, 0x05, 0xce, + 0x4a, 0x8e, 0x73, 0x04, 0x2d, 0x27, 0x26, 0xb2, 0xd8, 0x6f, 0x88, 0x44, + 0xfc, 0x29, 0x91, 0xd3, 0xfe, 0x6f, 0x72, 0x5d, 0x4d, 0xbb, 0xfa, 0xe1, + 0x27, 0x85, 0x62, 0xc9, 0x01, 0x65, 0xb0, 0x3f, 0xb0, 0x22, 0x40, 0x77, + 0xd5, 0xe7, 0x28, 0xbe, 0xe2, 0x40, 0x22, 0x7e, 0x28, 0xb1, 0x7a, 0xfd, + 0x4f, 0x85, 0x0c, 0x79, 0xea, 0xf7, 0x48, 0x84, 0x11, 0x21, 0x76, 0x76, + 0x80, 0x9e, 0xb1, 0xa5, 0x12, 0xe9, 0xcc, 0xa2, 0x1d, 0xa6, 0x22, 0x57, + 0xfd, 0x7c, 0x30, 0x8d, 0x9e, 0x6c, 0x25, 0xe5, 0x06, 0x6d, 0xca, 0x59, + 0x90, 0xe5, 0x60, 0x57, 0x72, 0xfe, 0x38, 0x51, 0x04, 0xbd, 0xf4, 0xac, + 0x90, 0x74, 0x40, 0xfb, 0xf3, 0x27, 0x47, 0x52, 0xc2, 0x77, 0xfb, 0x36, + 0xe3, 0x68, 0x37, 0x36, 0x41, 0x6c, 0xe1, 0x00, 0x03, 0x29, 0xe0, 0xa7, + 0x18, 0xdb, 0xa4, 0xdb, 0x79, 0x2d, 0xce, 0xec, 0x81, 0xc7, 0x2b, 0xab, + 0x1f, 0xd6, 0xee, 0x84, 0x92, 0xfb, 0xa5, 0xf9, 0x55, 0xa9, 0xdc, 0xb3, + 0x81, 0x89, 0x64, 0xae, 0x79, 0x52, 0x60, 0x4d, 0xc0, 0x05, 0xd3, 0xa0, + 0xd1, 0xd2, 0x3a, 0x13, 0x4a, 0xee, 0x3e, 0x43, 0x64, 0x28, 0x5e, 0x2c, + 0x83, 0xdd, 0x5f, 0x09, 0xb1, 0xfd, 0x83, 0x34, 0xf6, 0x50, 0x40, 0x1b, + 0x31, 0x84, 0x2f, 0x04, 0x3e, 0x45, 0x5b, 0x9a, 0x54, 0x58, 0x43, 0x29, + 0x61, 0x2b, 0xa3, 0xf2, 0x82, 0x8d, 0xaf, 0xad, 0x4f, 0xf6, 0x82, 0xc3, + 0xe2, 0xd7, 0x29, 0x27, 0x8c, 0x1a, 0xc4, 0xb0, 0xb0, 0x46, 0x4a, 0x41, + 0x6d, 0x91, 0x63, 0xb4, 0x22, 0xe7, 0x35, 0x88, 0x2d, 0xb3, 0x75, 0x4d, + 0xfa, 0x9d, 0x75, 0x14, 0x9a, 0x2d, 0xa9, 0xc8, 0xa7, 0xbe, 0xe1, 0x52, + 0x7a, 0x6c, 0xd9, 0xf5, 0xa7, 0xf9, 0x06, 0x70, 0x7a, 0x25, 0x5d, 0x8b, + 0xbe, 0xb5, 0x1c, 0x2a, 0x20, 0xd3, 0xb2, 0x63, 0xe6, 0x33, 0x02, 0xd3, + 0xcd, 0xca, 0x4f, 0x0a, 0xcc, 0x29, 0x7a, 0x26, 0x46, 0x16, 0x95, 0x04, + 0x3b, 0x49, 0x99, 0x6a, 0xa7, 0xb6, 0xd5, 0x06, 0xcc, 0x4e, 0x43, 0x2b, + 0x95, 0x1e, 0xc9, 0xdd, 0xec, 0xf5, 0x01, 0x47, 0x2d, 0x2d, 0xc9, 0xe2, + 0x4f, 0x55, 0x6a, 0x6f, 0x8c, 0x42, 0x21, 0x2d, 0xc5, 0xd8, 0x02, 0xb1, + 0x1b, 0x06, 0xa0, 0x08, 0xc6, 0x1b, 0x9e, 0x78, 0x21, 0xaa, 0x7d, 0x9a, + 0xba, 0x8a, 0xc1, 0xf0, 0xc4, 0xcf, 0xa2, 0x3a, 0x51, 0x1f, 0xc9, 0xf2, + 0xa6, 0x48, 0xb4, 0x56, 0xb4, 0xbe, 0x62, 0x6f, 0xf6, 0xeb, 0x22, 0x7a, + 0x11, 0xe5, 0x95, 0x22, 0xa3, 0xde, 0x88, 0x3a, 0x02, 0xf2, 0xc3, 0x74, + 0x57, 0xa8, 0x8a, 0xf7, 0x79, 0x33, 0x02, 0xef, 0x71, 0xda, 0x56, 0x55, + 0xc5, 0xa2, 0xa0, 0x56, 0x3c, 0xbe, 0xfe, 0x5c, 0x80, 0x54, 0xfc, 0xe1, + 0x2e, 0x52, 0xfe, 0x87, 0x3b, 0xde, 0x8c, 0xd2, 0xdd, 0xe2, 0x35, 0xd1, + 0x74, 0x65, 0xcf, 0x12, 0xa5, 0x4f, 0xda, 0x0f, 0x38, 0x16, 0xe6, 0xd4, + 0x07, 0xe8, 0x37, 0x07, 0x13, 0xca, 0x43, 0x1e, 0x34, 0x35, 0x10, 0xfb, + 0xf5, 0x80, 0xca, 0x4e, 0xf9, 0xf6, 0xa6, 0x11, 0x83, 0x5d, 0x85, 0xf2, + 0xe8, 0x86, 0x21, 0x53, 0xa7, 0x0d, 0x79, 0xcc, 0xcc, 0x6f, 0x83, 0x89, + 0xd2, 0x29, 0x54, 0x05, 0x67, 0x53, 0x3f, 0xda, 0x5b, 0x47, 0xb4, 0xe1, + 0x6c, 0xa4, 0x43, 0x18, 0xaf, 0x0f, 0xe7, 0xf3, 0x1a, 0xd0, 0x34, 0xd3, + 0x13, 0x07, 0xf2, 0x83, 0xeb, 0x28, 0xde, 0x1e, 0xbb, 0x16, 0x6b, 0xf9, + 0x05, 0xec, 0x21, 0xb4, 0xf9, 0x45, 0x17, 0xd0, 0x93, 0x9b, 0xd8, 0x5d, + 0x10, 0x56, 0x3d, 0xa5, 0x89, 0x68, 0x45, 0xe6, 0xa9, 0x44, 0xfc, 0x89, + 0x11, 0x7a, 0x76, 0xdd, 0x66, 0x94, 0x1c, 0x57, 0x94, 0x9e, 0xe2, 0x42, + 0x6b, 0x95, 0xfe, 0x49, 0xf7, 0x3f, 0x46, 0x4f, 0x5d, 0x2d, 0x2d, 0x96, + 0xec, 0x21, 0x28, 0x29, 0x96, 0x81, 0x31, 0x79, 0xe9, 0x39, 0x51, 0x28, + 0x81, 0xf2, 0x32, 0x4f, 0xd3, 0xdc, 0x99, 0xd6, 0x43, 0x33, 0x73, 0x41, + 0x2b, 0x66, 0xc3, 0x21, 0x41, 0xd5, 0xad, 0x96, 0x35, 0x62, 0x1b, 0xc5, + 0x7f, 0xc1, 0x52, 0xa1, 0x10, 0x34, 0xbb, 0xb4, 0x4f, 0xfc, 0x26, 0x0a, + 0xb1, 0x09, 0xfd, 0x94, 0xae, 0x9e, 0xe3, 0xee, 0x9e, 0x79, 0x40, 0xf8, + 0x67, 0xf7, 0x15, 0x79, 0xaf, 0xf0, 0xcf, 0x53, 0x9f, 0x46, 0x89, 0xcd, + 0x23, 0x74, 0x47, 0x69, 0x5f, 0x6a, 0xa4, 0x4c, 0x11, 0x6c, 0x59, 0xad, + 0x2d, 0xb3, 0xe9, 0xee, 0x3f, 0x49, 0x06, 0xdb, 0x1f, 0xa3, 0x7d, 0x1d, + 0x29, 0xc0, 0xc2, 0xcc, 0xd1, 0x56, 0x18, 0xe8, 0x3e, 0x56, 0xa5, 0x15, + 0xe3, 0x03, 0xa7, 0xda, 0x43, 0x0f, 0x9f, 0x6e, 0xdf, 0x2a, 0x68, 0x25, + 0x55, 0xd1, 0xb7, 0xbc, 0x53, 0x03, 0x3f, 0x30, 0xab, 0x6e, 0x3e, 0x12, + 0x82, 0xe2, 0x2c, 0xa9, 0x37, 0x60, 0x35, 0x6c, 0xe6, 0xc8, 0xf4, 0xcc, + 0x50, 0x4f, 0x3b, 0xd8, 0xe8, 0xc9, 0x35, 0x74, 0xaf, 0xf1, 0xaa, 0x81, + 0x6f, 0x68, 0x8d, 0xb6, 0xa6, 0xaf, 0xd3, 0xd1, 0x10, 0x11, 0xbe, 0x90, + 0x6d, 0xb5, 0x9f, 0x47, 0x63, 0x1d, 0xb4, 0x07, 0x35, 0x08, 0xed, 0xa5, + 0x71, 0xcf, 0x99, 0xbf, 0x37, 0xf3, 0xb1, 0x23, 0x3f, 0x42, 0x1a, 0x52, + 0xc9, 0x8f, 0x0a, 0xe4, 0x14, 0x14, 0x40, 0x21, 0xc4, 0xfe, 0xdc, 0xe7, + 0xc0, 0x61, 0x44, 0xa9, 0x0b, 0xfb, 0x9d, 0x52, 0x78, 0xa9, 0x5a, 0xa6, + 0x34, 0x0f, 0xb1, 0xf7, 0xfa, 0xe8, 0xb8, 0x02, 0x9e, 0x09, 0x93, 0xb0, + 0xc9, 0xe7, 0x40, 0xed, 0xc1, 0x54, 0xe5, 0xc4, 0x3e, 0x9b, 0x92, 0x80, + 0xe2, 0x4f, 0x7b, 0x6c, 0x28, 0x79, 0x13, 0xf1, 0x07, 0x86, 0xa1, 0x38, + 0x2a, 0xa7, 0xfc, 0x6f, 0xb9, 0x90, 0xed, 0xf5, 0xcb, 0xd1, 0x17, 0xb0, + 0x6f, 0x69, 0x9f, 0xd2, 0xfe, 0x4d, 0xca, 0x78, 0x88, 0xfd, 0xa4, 0x8f, + 0x62, 0x8e, 0x96, 0xd5, 0xc8, 0x2d, 0x9a, 0xb9, 0x43, 0xa1, 0xef, 0xcd, + 0x14, 0xbf, 0x88, 0xbb, 0x37, 0xc6, 0x25, 0xe2, 0xcf, 0xa0, 0x5c, 0x1f, + 0x70, 0x98, 0x3a, 0xa8, 0xae, 0x04, 0x76, 0x7a, 0xae, 0x65, 0x22, 0x7e, + 0x2e, 0x41, 0xbf, 0xbf, 0x00, 0x6f, 0xbc, 0x95, 0x42, 0x66, 0xf4, 0xd1, + 0xf3, 0x61, 0xd5, 0x58, 0x8a, 0x0b, 0x8c, 0xf4, 0x24, 0x9c, 0x11, 0x92, + 0xa7, 0x3e, 0x53, 0x8c, 0xdc, 0x20, 0x11, 0x2f, 0x1a, 0xa6, 0xf3, 0x65, + 0xb6, 0xd7, 0xe9, 0xec, 0xdd, 0xec, 0xc4, 0x17, 0x28, 0x2f, 0x68, 0xfd, + 0x14, 0x8e, 0x78, 0xc7, 0x3f, 0xae, 0xa8, 0x37, 0xcf, 0xe0, 0x2d, 0x1e, + 0x13, 0x90, 0x66, 0xd3, 0xd4, 0xa4, 0x14, 0xe3, 0xae, 0x91, 0x62, 0xa4, + 0x68, 0x32, 0x3c, 0xea, 0xc9, 0x9e, 0x3b, 0xc6, 0xb7, 0xb2, 0xde, 0x1a, + 0xb2, 0xc0, 0x9b, 0x9e, 0x5d, 0x95, 0xb5, 0x95, 0xe0, 0x28, 0x13, 0x0c, + 0x52, 0xc6, 0xad, 0x0d, 0xcb, 0x1f, 0x83, 0x9f, 0x2f, 0xfa, 0x85, 0x90, + 0x7e, 0x3c, 0xbd, 0xc6, 0x58, 0xdd, 0xe6, 0x3d, 0xb8, 0x30, 0x65, 0x54, + 0x7a, 0x69, 0xab, 0x53, 0x14, 0xe9, 0x45, 0xcf, 0xe7, 0x6b, 0x9a, 0x8d, + 0x32, 0x4c, 0xd4, 0x56, 0x8b, 0xb0, 0x84, 0xcb, 0x09, 0xe4, 0xf8, 0x3f, + 0x8d, 0x16, 0x53, 0x19, 0x8b, 0x32, 0xa2, 0x0c, 0x65, 0xca, 0xa3, 0x88, + 0x87, 0x82, 0x2c, 0xb0, 0x49, 0x33, 0xd4, 0x1e, 0xba, 0x33, 0x9e, 0xa9, + 0xa1, 0x23, 0x61, 0x43, 0x3f, 0x9d, 0x4f, 0xf9, 0x1c, 0xe5, 0xcd, 0x65, + 0x2b, 0xf2, 0x6b, 0xdf, 0xa2, 0xe5, 0x06, 0x68, 0x59, 0xbe, 0x68, 0xf9, + 0x76, 0x45, 0xd3, 0xa3, 0x79, 0xd5, 0xbe, 0xc5, 0xe8, 0x1b, 0x3a, 0xbe, + 0x1d, 0xfb, 0x3f, 0xb2, 0x7c, 0xb3, 0x00, 0xc7, 0x83, 0xb3, 0x17, 0x2f, + 0x8f, 0x47, 0x69, 0x5c, 0xfc, 0xaa, 0xee, 0xb4, 0x05, 0x90, 0xa3, 0xe4, + 0xdc, 0x56, 0xf1, 0xf5, 0xe8, 0x68, 0x03, 0xf3, 0xad, 0x24, 0x0c, 0x13, + 0xad, 0xca, 0xbc, 0xde, 0x2d, 0x83, 0x3f, 0x10, 0x52, 0xa4, 0x32, 0x45, + 0x77, 0x9a, 0x3d, 0x48, 0x94, 0xb1, 0xe8, 0x1c, 0x24, 0x7c, 0x9b, 0x27, + 0x03, 0xe5, 0x65, 0x86, 0x8f, 0x44, 0x9e, 0x9e, 0x97, 0x6c, 0x4f, 0x85, + 0x1f, 0x14, 0x0e, 0x12, 0xef, 0x4c, 0xf1, 0xed, 0x83, 0xa7, 0xe7, 0x11, + 0xc7, 0x3e, 0x8f, 0x01, 0x35, 0xd5, 0x94, 0x50, 0xd8, 0x9b, 0x12, 0x2c, + 0x53, 0xf2, 0x27, 0x75, 0xb0, 0x94, 0xc1, 0x4b, 0x4a, 0xfb, 0x2e, 0xdd, + 0x85, 0x7a, 0xa5, 0x5f, 0xed, 0xa1, 0x6d, 0xa3, 0xed, 0xa4, 0xf2, 0x24, + 0x0f, 0x69, 0x9d, 0x34, 0xd3, 0xf9, 0xd3, 0x1f, 0xe3, 0x28, 0x9a, 0x2d, + 0x13, 0x71, 0x8b, 0x30, 0xeb, 0xd4, 0xd5, 0x59, 0x41, 0xfb, 0xb5, 0x78, + 0x2f, 0x7c, 0xde, 0x93, 0xe7, 0xcb, 0xbb, 0x0d, 0x47, 0x7c, 0xd8, 0xe9, + 0xed, 0x69, 0x47, 0x3b, 0x35, 0x62, 0xf1, 0xa1, 0x9d, 0x1d, 0xe1, 0x73, + 0x45, 0xf8, 0x5e, 0xfd, 0xe9, 0xdb, 0xb9, 0x9a, 0x36, 0xd8, 0x33, 0xaf, + 0x62, 0xb9, 0x53, 0x30, 0xe0, 0x48, 0x4a, 0x42, 0x69, 0x42, 0xa8, 0x55, + 0x0a, 0x9c, 0x94, 0x66, 0xe9, 0xf9, 0xac, 0x3f, 0x16, 0x62, 0xdd, 0x8c, + 0x52, 0xcf, 0x27, 0xdd, 0x28, 0x41, 0x22, 0xc4, 0x16, 0x16, 0x3e, 0x94, + 0x50, 0xfb, 0x85, 0x1c, 0xcf, 0x3e, 0x8f, 0xce, 0x77, 0x53, 0xdd, 0xf7, + 0xea, 0x2d, 0xa8, 0xb3, 0x42, 0xc4, 0x12, 0x3c, 0x83, 0x63, 0xf5, 0xbc, + 0x02, 0x3b, 0x85, 0x97, 0xe2, 0x91, 0xf6, 0x0d, 0xd5, 0x61, 0x4d, 0x1d, + 0xc9, 0x93, 0x9a, 0x0d, 0xd5, 0x29, 0x5f, 0x63, 0x92, 0xea, 0xaf, 0xda, + 0x1a, 0x5d, 0x55, 0x56, 0x1d, 0x13, 0x8a, 0x78, 0x99, 0xd1, 0x7e, 0x4f, + 0xf1, 0xd3, 0xf3, 0x9b, 0x69, 0xdf, 0x5d, 0xdb, 0xc7, 0xff, 0x7b, 0x79, + 0x1b, 0xc4, 0x11, 0x6a, 0x44, 0xbd, 0x08, 0x4a, 0x32, 0x25, 0x3a, 0x33, + 0xd5, 0x18, 0x58, 0xaf, 0xc8, 0x42, 0x8d, 0x54, 0x8a, 0x34, 0xec, 0x0a, + 0xd0, 0x93, 0x61, 0xe8, 0x39, 0xbf, 0x0e, 0x1c, 0x23, 0xd4, 0xf7, 0x97, + 0xc4, 0x04, 0xf8, 0x2a, 0x4a, 0xd0, 0x7a, 0x70, 0x75, 0xb0, 0x0f, 0x6f, + 0x5e, 0xef, 0x5d, 0xcf, 0x04, 0xde, 0x5e, 0xaf, 0xb2, 0x11, 0xf7, 0xd9, + 0xf6, 0xc3, 0xa8, 0x61, 0x00, 0xef, 0xf7, 0x66, 0x72, 0xaa, 0xe9, 0x0b, + 0xb0, 0x7c, 0x02, 0x8b, 0xbc, 0xb7, 0x73, 0xaa, 0x69, 0x64, 0xca, 0xdc, + 0xe0, 0x67, 0x51, 0xa4, 0xb1, 0xf5, 0x82, 0x7f, 0x8b, 0x3f, 0x11, 0xef, + 0x4d, 0x24, 0x4f, 0x5f, 0x80, 0x92, 0x5c, 0x49, 0x1d, 0x50, 0xd9, 0x54, + 0xe0, 0x43, 0xf8, 0x3e, 0x46, 0x79, 0x0e, 0xa5, 0xd9, 0x12, 0x14, 0xcd, + 0xf3, 0xaa, 0xa6, 0x16, 0x73, 0xb7, 0x84, 0x2a, 0x83, 0xf7, 0x04, 0x69, + 0xcf, 0xbe, 0x90, 0x28, 0x01, 0x8d, 0xd2, 0xc7, 0x17, 0x13, 0x65, 0xc0, + 0x28, 0xae, 0x36, 0xba, 0xcb, 0x1f, 0xe1, 0x42, 0x5d, 0x70, 0xfc, 0xcd, + 0x70, 0xab, 0x57, 0x15, 0x50, 0xdd, 0x9c, 0x0a, 0xad, 0x77, 0x27, 0xfb, + 0x59, 0x4a, 0x10, 0xe5, 0x3c, 0xca, 0x0b, 0x0f, 0x83, 0x93, 0x95, 0xbe, + 0xe3, 0xe5, 0x03, 0x1f, 0x98, 0x55, 0x33, 0xbe, 0x17, 0xbc, 0xb4, 0xde, + 0x11, 0x80, 0x62, 0x35, 0x4a, 0x11, 0xb0, 0x7b, 0xbd, 0xc7, 0x39, 0x55, + 0x45, 0x6b, 0x10, 0xc7, 0xb6, 0x79, 0x41, 0x70, 0x04, 0x21, 0xba, 0xe5, + 0x61, 0x03, 0xb6, 0x92, 0x9e, 0xb6, 0x70, 0x22, 0xe1, 0x5f, 0x5f, 0x0c, + 0xc9, 0xf3, 0x2d, 0x74, 0x79, 0x5a, 0xa9, 0xfe, 0xe1, 0x1d, 0x82, 0x5a, + 0x4e, 0xd2, 0xe9, 0xc7, 0x09, 0x62, 0x0b, 0x76, 0xaa, 0x8a, 0xdc, 0x08, + 0x75, 0x61, 0x80, 0xc2, 0x1d, 0x09, 0x99, 0xf2, 0xbe, 0x94, 0xd6, 0x79, + 0x55, 0xd3, 0xf7, 0x73, 0x07, 0xef, 0xda, 0x8e, 0x7a, 0xc3, 0xe2, 0x10, + 0x13, 0xa4, 0xe7, 0xf8, 0x52, 0x4d, 0x83, 0x94, 0xd3, 0xaf, 0xa3, 0xb5, + 0x0f, 0x27, 0xe1, 0x9e, 0x8d, 0x25, 0xff, 0x2d, 0x0a, 0xa5, 0xff, 0x18, + 0x4d, 0x2f, 0x84, 0xb6, 0x0b, 0x71, 0x4c, 0x2f, 0x04, 0x2f, 0x63, 0x5f, + 0x8c, 0xc5, 0xd1, 0x63, 0x46, 0x08, 0x54, 0xb1, 0xcf, 0xfa, 0x4a, 0x20, + 0x98, 0xa3, 0x8a, 0x3d, 0x3c, 0x04, 0xfc, 0xe5, 0x4d, 0xcf, 0x6f, 0xf2, + 0xfb, 0xdb, 0xfc, 0xc1, 0xd1, 0xb3, 0x20, 0xe6, 0xf4, 0x13, 0xe5, 0xfb, + 0xee, 0x99, 0xbe, 0x7f, 0x3f, 0x25, 0x62, 0xc6, 0x68, 0xcc, 0xfb, 0x7d, + 0xdf, 0x9c, 0x12, 0xf1, 0xef, 0xf6, 0x0d, 0x3d, 0x33, 0x22, 0x0d, 0x92, + 0x1c, 0x27, 0x11, 0x8f, 0x25, 0xd4, 0x70, 0x04, 0x79, 0xbd, 0x1e, 0xed, + 0x1a, 0xe6, 0xb8, 0x0e, 0x7f, 0xc9, 0x71, 0xe4, 0x8b, 0x03, 0x68, 0x95, + 0x4d, 0x16, 0x03, 0xcf, 0xc1, 0x65, 0x65, 0x1c, 0x52, 0x8e, 0x52, 0x0c, + 0x7d, 0x9d, 0x5d, 0xa8, 0xdf, 0xfe, 0x91, 0xae, 0x71, 0xc0, 0x72, 0xfe, + 0x77, 0xe7, 0x6b, 0xf4, 0x75, 0xa4, 0x61, 0x4b, 0x60, 0x3c, 0x29, 0xfc, + 0xa5, 0x40, 0x64, 0x9a, 0xfb, 0x5f, 0xcf, 0xd7, 0x50, 0x7b, 0xc8, 0x0d, + 0x68, 0x63, 0x43, 0xba, 0xcf, 0xd4, 0xd1, 0xc5, 0x79, 0x85, 0x85, 0x33, + 0xb7, 0x40, 0x6a, 0x55, 0xce, 0x42, 0xc2, 0xdb, 0x6c, 0x3b, 0x3c, 0x1e, + 0x0b, 0xa9, 0x80, 0xd2, 0xd4, 0x1e, 0x94, 0x99, 0x67, 0xc2, 0xc8, 0x25, + 0x73, 0xa8, 0xed, 0x83, 0x5c, 0xd9, 0x84, 0x26, 0xf1, 0x66, 0x4f, 0xb6, + 0x30, 0x20, 0x91, 0xa9, 0x50, 0xdc, 0x77, 0xfa, 0x8b, 0x28, 0xfd, 0xe6, + 0x93, 0x83, 0x63, 0x5d, 0x8d, 0x76, 0xc1, 0x7b, 0xdf, 0x02, 0x27, 0xe9, + 0x89, 0x08, 0x99, 0x72, 0xca, 0x86, 0xdd, 0x95, 0x9c, 0xef, 0xde, 0xca, + 0xb7, 0xb8, 0xbb, 0x84, 0xbb, 0x66, 0x8e, 0xf5, 0x91, 0x5d, 0xd4, 0xd2, + 0xa6, 0x67, 0x5d, 0x91, 0x8a, 0xb0, 0x27, 0x17, 0x0a, 0x3d, 0xbc, 0x30, + 0x56, 0xca, 0x40, 0xdb, 0x59, 0x35, 0x70, 0x6b, 0x28, 0x3d, 0x74, 0x3d, + 0x73, 0xb3, 0xf7, 0x27, 0xa1, 0x19, 0xec, 0x0d, 0xde, 0x3f, 0x87, 0xae, + 0xd7, 0xdc, 0xec, 0x5d, 0x03, 0xaf, 0x2f, 0xf9, 0x7e, 0x0a, 0xc8, 0xaf, + 0x73, 0xdf, 0x32, 0x67, 0x5e, 0xff, 0x0a, 0xdc, 0x30, 0x8f, 0x4c, 0xb9, + 0xf7, 0x96, 0xbf, 0x1f, 0x27, 0x11, 0x55, 0x75, 0x33, 0xf0, 0xde, 0x05, + 0xf3, 0xe2, 0xca, 0x5a, 0x84, 0x64, 0xdd, 0xd9, 0x40, 0x4c, 0x7a, 0x5f, + 0xd6, 0x68, 0x3b, 0x74, 0x35, 0x8f, 0x02, 0x34, 0x6b, 0xab, 0x1c, 0x70, + 0x21, 0x87, 0x89, 0x7d, 0x3a, 0x82, 0xd2, 0xee, 0x0c, 0x58, 0xc7, 0x76, + 0x52, 0xf8, 0x07, 0x15, 0x78, 0x0b, 0x31, 0x7d, 0xd4, 0x4a, 0xe5, 0x10, + 0x1d, 0x7d, 0x4c, 0xec, 0xe9, 0x11, 0xb5, 0x43, 0x0d, 0xfb, 0xbe, 0x65, + 0xdf, 0x40, 0x65, 0xc5, 0x83, 0x09, 0xa4, 0xe2, 0xc9, 0x74, 0x6e, 0x15, + 0x2d, 0xa9, 0x98, 0x38, 0xd2, 0xdb, 0x1e, 0x54, 0xce, 0xfa, 0x48, 0xc5, + 0x51, 0xc0, 0xc4, 0x7e, 0x88, 0x69, 0xb5, 0x70, 0xf0, 0x5b, 0x2e, 0x28, + 0xd9, 0x90, 0x88, 0xfb, 0x13, 0x6c, 0x1e, 0x73, 0x1a, 0xad, 0x87, 0xd8, + 0x33, 0xa8, 0x05, 0x94, 0x28, 0xa7, 0xb1, 0x7d, 0x37, 0x41, 0x67, 0xd9, + 0x37, 0x8e, 0xd0, 0x33, 0x97, 0xbb, 0x2a, 0x29, 0x6c, 0xb1, 0x0e, 0x52, + 0xf8, 0x23, 0x0f, 0x1b, 0x38, 0xec, 0x65, 0xfd, 0x5c, 0xc1, 0x1c, 0x2f, + 0x6b, 0x2e, 0x84, 0x77, 0xa7, 0x80, 0xb3, 0x54, 0xca, 0x0b, 0x4c, 0xf2, + 0xdf, 0x13, 0x58, 0xed, 0xdf, 0x13, 0xe8, 0x09, 0xfc, 0xdc, 0x7f, 0x66, + 0x32, 0xaf, 0xc4, 0x17, 0x42, 0x23, 0x2f, 0x4d, 0xb9, 0xc5, 0xbc, 0x84, + 0x38, 0xbd, 0x8d, 0x85, 0x13, 0x35, 0xb9, 0xfe, 0x5c, 0x7f, 0xba, 0x2f, + 0x35, 0x77, 0x87, 0x67, 0x8b, 0x9f, 0xf0, 0xf9, 0xf0, 0xa2, 0xe7, 0x26, + 0xd0, 0x95, 0xed, 0xf0, 0x68, 0x02, 0x53, 0xbc, 0x6a, 0xbf, 0x3a, 0xe0, + 0xf4, 0xaa, 0xfc, 0xf9, 0x3c, 0x98, 0x2d, 0x9e, 0x6e, 0x17, 0xe3, 0x8f, + 0x75, 0x36, 0x16, 0x3d, 0xc8, 0x4c, 0xf2, 0xf7, 0xe1, 0xef, 0x6a, 0x7f, + 0x57, 0xd1, 0xf5, 0xaa, 0x9f, 0xfb, 0xe5, 0x28, 0xdd, 0xad, 0x7c, 0xf5, + 0xbc, 0x82, 0x79, 0x28, 0x07, 0x8f, 0xd6, 0x2a, 0xfb, 0xd9, 0xab, 0x98, + 0xd8, 0x88, 0xb2, 0xae, 0xa3, 0x44, 0xe1, 0xd5, 0xc0, 0x93, 0xc2, 0xf4, + 0x22, 0x32, 0xad, 0x15, 0x35, 0x04, 0x93, 0x93, 0x91, 0xc1, 0xf1, 0xe6, + 0x1d, 0xb1, 0xce, 0x7c, 0xd0, 0xcf, 0xb9, 0xce, 0xb3, 0x58, 0xb7, 0xef, + 0xae, 0x1b, 0xe1, 0x3e, 0xe1, 0xbe, 0x99, 0xaf, 0xc3, 0xf4, 0x99, 0xe5, + 0x9e, 0x13, 0xed, 0xe3, 0xe1, 0x86, 0x1b, 0xf4, 0xa5, 0x70, 0x46, 0x3b, + 0xe3, 0xf7, 0x77, 0x10, 0xf7, 0xc5, 0x68, 0xc9, 0x28, 0xbf, 0xa7, 0x5a, + 0x87, 0xaa, 0x99, 0x89, 0x2d, 0x1a, 0x61, 0xf3, 0x4a, 0x65, 0xe2, 0x18, + 0x33, 0x37, 0x03, 0xb5, 0x0c, 0xb5, 0x0d, 0x9e, 0x60, 0x62, 0xdf, 0x1e, + 0x51, 0x89, 0xe5, 0x40, 0xec, 0xd8, 0xf7, 0xe1, 0x0a, 0xc4, 0xd3, 0x9d, + 0x09, 0x55, 0xab, 0x0b, 0x36, 0x78, 0x21, 0x26, 0xf4, 0x6b, 0x20, 0x15, + 0x35, 0x0d, 0xc6, 0x0e, 0x61, 0xd6, 0xc6, 0xc4, 0x84, 0x11, 0x37, 0x38, + 0x30, 0x25, 0xe6, 0x7b, 0x92, 0x89, 0x55, 0x8c, 0x38, 0x81, 0x71, 0xd8, + 0x41, 0xa3, 0x94, 0x32, 0x79, 0x44, 0xd1, 0x4e, 0x56, 0x9e, 0x61, 0x94, + 0xf3, 0xb4, 0xad, 0xbf, 0x44, 0xbb, 0xe5, 0x87, 0x47, 0x98, 0x26, 0xd6, + 0xa6, 0xda, 0xc9, 0x36, 0xab, 0xc3, 0x4c, 0x4c, 0x9b, 0x18, 0xb0, 0xef, + 0x2d, 0xda, 0x86, 0x5a, 0xc6, 0xd8, 0xfe, 0xf2, 0xc2, 0x07, 0xa1, 0xd2, + 0x4b, 0x9a, 0x12, 0x53, 0xc6, 0xf9, 0xc6, 0xd5, 0x5c, 0xe1, 0xb4, 0x05, + 0x61, 0x21, 0xfd, 0x14, 0x11, 0xc9, 0x4d, 0x5f, 0x59, 0x60, 0xe2, 0x17, + 0x38, 0x3a, 0xf2, 0x7b, 0x41, 0x24, 0x33, 0xac, 0x56, 0x08, 0xc3, 0x75, + 0x1a, 0x99, 0xdc, 0x08, 0x13, 0xfe, 0x21, 0xf1, 0x30, 0x1e, 0xea, 0xbd, + 0x10, 0x76, 0x01, 0xb4, 0x42, 0xec, 0x4a, 0x1f, 0x23, 0xb6, 0x08, 0x1f, + 0xa3, 0x8d, 0xff, 0x77, 0x79, 0x80, 0x27, 0x36, 0x11, 0xee, 0xf1, 0xaa, + 0xc4, 0x3c, 0x3f, 0x2b, 0xe6, 0xf8, 0xd5, 0x62, 0xbe, 0xf2, 0x55, 0x78, + 0xde, 0x8f, 0xbf, 0x48, 0xcc, 0xeb, 0x33, 0xc2, 0xd7, 0x67, 0x90, 0xdc, + 0x5a, 0xe0, 0x2b, 0x98, 0xeb, 0xf6, 0x9b, 0xe1, 0x60, 0x60, 0x27, 0x3d, + 0x81, 0x64, 0x0e, 0xef, 0xdb, 0x2d, 0x14, 0x1c, 0x67, 0x62, 0x37, 0x8f, + 0xd8, 0x7d, 0xee, 0x6b, 0x4e, 0x20, 0xc9, 0xbf, 0xe6, 0x04, 0x92, 0xbc, + 0xd1, 0x13, 0x48, 0xf2, 0xbe, 0x3e, 0x81, 0xe4, 0xa5, 0xc4, 0xf3, 0xfe, + 0x91, 0x38, 0x93, 0x48, 0xc4, 0x77, 0xf5, 0x25, 0xe2, 0xdf, 0x1a, 0xe0, + 0xe6, 0x98, 0xaf, 0x9e, 0x40, 0xf2, 0xc7, 0x7f, 0x3f, 0x81, 0xe4, 0x37, + 0xc3, 0xc9, 0x13, 0x48, 0x0e, 0x0c, 0x5f, 0x3d, 0x81, 0x04, 0xc7, 0xc9, + 0xd5, 0x33, 0x48, 0x46, 0xcf, 0x1f, 0xa1, 0x67, 0x91, 0xf8, 0x8d, 0x48, + 0xff, 0xc6, 0x6f, 0xce, 0x20, 0x31, 0xa1, 0x9b, 0x86, 0x5d, 0x3d, 0x83, + 0x24, 0x78, 0x75, 0xdd, 0xd0, 0x6f, 0x87, 0xa3, 0xba, 0x1a, 0x15, 0x64, + 0x04, 0xa8, 0xdc, 0xd2, 0x56, 0x67, 0xf8, 0x4d, 0x01, 0x4d, 0xf5, 0x5b, + 0xdc, 0x0e, 0x81, 0x74, 0xd3, 0x59, 0x9c, 0xe4, 0xa8, 0xea, 0xaa, 0x5c, + 0x9a, 0x9d, 0x5c, 0xbf, 0xa4, 0xac, 0x7d, 0xc2, 0x3c, 0x59, 0x68, 0xd7, + 0x9a, 0x41, 0xeb, 0xa3, 0x67, 0x6a, 0x6a, 0x7c, 0x16, 0x94, 0x0b, 0x10, + 0x66, 0x80, 0x07, 0xb6, 0x8a, 0x8d, 0xc9, 0x43, 0x34, 0x45, 0x57, 0x65, + 0x35, 0x8e, 0x8d, 0x8c, 0x61, 0x30, 0x7d, 0x0b, 0xdf, 0xe9, 0x2f, 0x6b, + 0x3b, 0xb4, 0x18, 0x37, 0x73, 0x98, 0x9e, 0x59, 0xac, 0x95, 0xd4, 0x07, + 0x38, 0x20, 0x3b, 0xd5, 0x31, 0xef, 0x88, 0x0a, 0x43, 0xaf, 0x1f, 0xa6, + 0x39, 0x1e, 0xc3, 0x74, 0xa6, 0x61, 0x4a, 0xb7, 0xf4, 0x3c, 0x94, 0xcb, + 0x89, 0x27, 0xd0, 0x9f, 0xa9, 0x9c, 0x6d, 0x32, 0xe6, 0x58, 0xd3, 0x32, + 0xf9, 0x3f, 0x9c, 0x6d, 0xd2, 0x68, 0xd7, 0x6b, 0xde, 0x1c, 0x77, 0xbb, + 0x87, 0x5a, 0x26, 0xef, 0x7a, 0xf5, 0xb1, 0xb7, 0x07, 0xe8, 0x09, 0x27, + 0xd7, 0x9e, 0x6f, 0x72, 0xe1, 0xdf, 0xce, 0x37, 0xf9, 0x3f, 0x3b, 0x2b, + 0x45, 0x1f, 0x7b, 0x66, 0xe0, 0x7f, 0x7f, 0x56, 0xca, 0xae, 0xca, 0x5b, + 0x6b, 0x9a, 0xd7, 0x34, 0xeb, 0xea, 0x2a, 0xc9, 0x31, 0x57, 0x2f, 0x4d, + 0x5b, 0x73, 0x6b, 0xc7, 0x9a, 0x55, 0xba, 0xa1, 0xe3, 0x93, 0x57, 0x3f, + 0xb0, 0xfa, 0xa1, 0x35, 0xd7, 0xaf, 0x81, 0x58, 0x61, 0xdf, 0xae, 0xca, + 0x59, 0x35, 0x57, 0xf3, 0xd5, 0x55, 0x52, 0xdb, 0x69, 0x57, 0xa5, 0xe7, + 0xeb, 0x7c, 0x0b, 0x95, 0x7c, 0x37, 0xfe, 0x8f, 0x7c, 0x73, 0x31, 0xdf, + 0xf5, 0xff, 0x96, 0x0f, 0x9c, 0x05, 0x3d, 0x19, 0x12, 0x94, 0xdc, 0x7c, + 0x1a, 0x3a, 0x8e, 0x7a, 0x3d, 0x02, 0xc8, 0xa4, 0x0c, 0x62, 0x53, 0xfb, + 0xae, 0xba, 0x7b, 0xbc, 0xf3, 0xe9, 0xdb, 0x0d, 0x9d, 0x50, 0x8a, 0x94, + 0x5c, 0x8c, 0xfa, 0x3e, 0xb6, 0x10, 0x79, 0x41, 0xfa, 0x51, 0x2d, 0x91, + 0xbb, 0xbc, 0x33, 0x75, 0xd0, 0xa1, 0x8f, 0x59, 0x06, 0x70, 0xd8, 0xf1, + 0x98, 0xa6, 0x03, 0x4a, 0x0c, 0x3d, 0x5f, 0xe7, 0x89, 0x65, 0x7f, 0x5d, + 0x0e, 0x74, 0xfe, 0x8f, 0x12, 0x63, 0xea, 0xbe, 0x6b, 0x4a, 0x2f, 0xe1, + 0x65, 0x70, 0x72, 0xf4, 0xcb, 0x9d, 0xf4, 0x5a, 0x65, 0xea, 0x6d, 0x53, + 0x97, 0x7d, 0x77, 0x19, 0xaa, 0x33, 0x7c, 0x12, 0x97, 0xdf, 0x5d, 0x33, + 0x75, 0xcd, 0x7d, 0x95, 0x41, 0x7a, 0x8e, 0x9e, 0xa4, 0xad, 0x22, 0x40, + 0xeb, 0xec, 0xed, 0x4f, 0xd6, 0x49, 0xed, 0x81, 0xe4, 0x8c, 0x05, 0xc5, + 0x9f, 0x72, 0xae, 0x04, 0x5a, 0xf9, 0xaf, 0xf7, 0x66, 0x19, 0xd1, 0x3a, + 0x2b, 0x8d, 0x4a, 0x8d, 0x2f, 0x67, 0xdc, 0x36, 0x0d, 0x4b, 0xa3, 0xe5, + 0xb8, 0x5e, 0x66, 0x8d, 0x0f, 0xaf, 0x99, 0xb6, 0xc6, 0xca, 0xf2, 0xde, + 0x8a, 0xd1, 0xb0, 0x04, 0x52, 0xd5, 0xa3, 0xed, 0x0f, 0xaf, 0xb9, 0xe9, + 0x5f, 0x42, 0x11, 0x33, 0xfc, 0x04, 0x76, 0xa2, 0x91, 0xd6, 0x0c, 0xe6, + 0x86, 0x99, 0x47, 0x5e, 0x4b, 0x96, 0x1f, 0xeb, 0xd8, 0x55, 0x09, 0x85, + 0xd9, 0x69, 0x44, 0xce, 0x64, 0x74, 0x53, 0xb2, 0xd3, 0xf1, 0x4d, 0xd8, + 0x29, 0xbb, 0xf0, 0xdd, 0x0c, 0xcc, 0x94, 0x13, 0xf8, 0x9e, 0x0f, 0x64, + 0xca, 0x89, 0x14, 0x32, 0xb9, 0xf0, 0xb6, 0x47, 0x96, 0x15, 0xce, 0xb9, + 0x71, 0x59, 0x9a, 0x31, 0xdc, 0x9e, 0xac, 0xe7, 0xc6, 0x35, 0xcb, 0xbc, + 0xd7, 0x1b, 0x1f, 0x52, 0xfd, 0xb6, 0x72, 0xbd, 0xf7, 0x83, 0x94, 0x25, + 0x6c, 0x97, 0xe5, 0xd7, 0x33, 0xb3, 0x8c, 0xeb, 0xbd, 0x3d, 0xdc, 0x51, + 0xcb, 0x9f, 0x75, 0x34, 0xee, 0x95, 0x59, 0xe1, 0xf6, 0xf5, 0xde, 0xfc, + 0x74, 0x2b, 0xb9, 0x1a, 0x97, 0x9f, 0x62, 0x55, 0x53, 0xf7, 0x0f, 0x52, + 0x7f, 0x82, 0xf2, 0x8e, 0xa6, 0xd1, 0x4f, 0x2c, 0xe8, 0x99, 0x6f, 0x58, + 0xe7, 0x6d, 0xb4, 0x3c, 0xa4, 0xaa, 0x34, 0xd0, 0x90, 0xb1, 0xfc, 0x12, + 0xeb, 0xdf, 0x3c, 0x1f, 0x78, 0x5e, 0x37, 0x2f, 0xad, 0x5c, 0xe6, 0xdd, + 0x6c, 0x0d, 0x56, 0xb2, 0x53, 0x34, 0x6e, 0x02, 0xa7, 0x3c, 0xfb, 0x3d, + 0x5d, 0x66, 0x38, 0x4e, 0xca, 0xf6, 0x09, 0x9a, 0x63, 0xc0, 0x2b, 0x14, + 0x36, 0x8a, 0xa3, 0x4c, 0x2b, 0x71, 0x5d, 0x39, 0xfe, 0xcf, 0xa8, 0x7e, + 0xfc, 0x46, 0xeb, 0x88, 0x67, 0x69, 0xe5, 0xbe, 0x76, 0x5a, 0x22, 0x1c, + 0x23, 0xd3, 0x1c, 0xc6, 0x75, 0xde, 0x2c, 0x63, 0x26, 0xbb, 0xd9, 0xd2, + 0x3a, 0x33, 0x05, 0x68, 0x59, 0x59, 0x37, 0x10, 0xe8, 0xc7, 0xb2, 0x1a, + 0x95, 0xb2, 0xe8, 0x8c, 0xf9, 0x3e, 0xc1, 0x70, 0x2c, 0xd6, 0x49, 0x5c, + 0xd4, 0x9f, 0x69, 0x1d, 0x38, 0x46, 0x2a, 0xfa, 0x30, 0x0c, 0xae, 0x09, + 0x8b, 0xa3, 0x25, 0x99, 0x63, 0x04, 0xa9, 0xb1, 0xd7, 0xf8, 0x32, 0x14, + 0xe6, 0x18, 0x58, 0xd9, 0xca, 0x8c, 0x4d, 0x73, 0x7b, 0x29, 0xd6, 0x72, + 0x52, 0xd0, 0x47, 0xc6, 0xa6, 0xa3, 0x0f, 0x71, 0xb7, 0x1b, 0x7d, 0x22, + 0x3c, 0x89, 0x3e, 0x8a, 0xc1, 0x33, 0x29, 0x8c, 0xdc, 0xcc, 0x2d, 0x99, + 0x49, 0xa6, 0xe4, 0xc0, 0x53, 0xdc, 0xd2, 0x99, 0x64, 0x72, 0x25, 0xe2, + 0xb1, 0x52, 0xc1, 0xe3, 0xd5, 0xde, 0xfa, 0x06, 0x8f, 0x4f, 0xb5, 0x3f, + 0xe4, 0xed, 0xb2, 0x52, 0xa8, 0x93, 0xbf, 0xcf, 0xa0, 0xff, 0xa8, 0xf5, + 0xa8, 0x75, 0x9c, 0xf1, 0x21, 0xef, 0xf7, 0xd9, 0x44, 0x4a, 0xa3, 0xf5, + 0xd7, 0x33, 0x93, 0x98, 0x35, 0x4e, 0x74, 0xf7, 0xbc, 0x32, 0x2b, 0x33, + 0x25, 0x5f, 0x3d, 0xdd, 0x6b, 0x4d, 0xf9, 0x26, 0x5f, 0x32, 0x07, 0x4d, + 0x7f, 0x33, 0x3b, 0xc3, 0x48, 0xd3, 0x5f, 0xc5, 0x74, 0x89, 0x82, 0x19, + 0xe3, 0x4d, 0x0f, 0x55, 0xbe, 0x88, 0x98, 0x75, 0xbd, 0xb6, 0xaf, 0xfd, + 0x10, 0xe2, 0x68, 0xbd, 0x97, 0xce, 0xed, 0x5c, 0xc5, 0x11, 0x75, 0x53, + 0xfa, 0x23, 0x37, 0x80, 0xf5, 0xc0, 0xcc, 0xfe, 0x63, 0xa1, 0x3c, 0xb0, + 0xc7, 0x3a, 0x8d, 0x4a, 0xce, 0x87, 0x2a, 0x37, 0xa6, 0xbc, 0xe8, 0x49, + 0x98, 0x7b, 0xa3, 0x50, 0x70, 0x77, 0x8e, 0x56, 0xca, 0xbe, 0xed, 0x7b, + 0xcb, 0xa6, 0x8d, 0x52, 0x1c, 0xa5, 0x85, 0x27, 0xda, 0xf7, 0xb4, 0xdf, + 0x8b, 0xf5, 0x78, 0xac, 0xbf, 0x98, 0x39, 0xc6, 0x98, 0x67, 0xa4, 0xee, + 0xeb, 0xd9, 0xeb, 0x8c, 0x37, 0x7b, 0x27, 0xb2, 0x34, 0xac, 0x55, 0x60, + 0x8f, 0x25, 0x6d, 0x5d, 0x5a, 0x26, 0x91, 0x9b, 0x84, 0xf8, 0x71, 0x5a, + 0x1f, 0x99, 0xdc, 0x2a, 0x7c, 0x7e, 0xfc, 0xab, 0xe8, 0x37, 0x7d, 0x59, + 0xe5, 0x99, 0xe9, 0xa9, 0xf2, 0x70, 0x2f, 0x5b, 0x7d, 0x4b, 0x02, 0x43, + 0x95, 0x24, 0xac, 0xeb, 0x64, 0x3f, 0x78, 0x78, 0x35, 0x98, 0xb8, 0x97, + 0xc7, 0xa1, 0x9d, 0x94, 0x0c, 0x81, 0x0f, 0x1e, 0xc3, 0x90, 0x5d, 0x95, + 0x59, 0x0a, 0x97, 0xd0, 0x1f, 0xab, 0xab, 0xe4, 0x5e, 0x4e, 0xf7, 0xf5, + 0x8c, 0xc6, 0x1a, 0x3f, 0xb8, 0x69, 0x2d, 0x98, 0x8c, 0x35, 0xdf, 0x70, + 0xa6, 0xba, 0xca, 0x44, 0xfc, 0xb3, 0x84, 0xae, 0xe6, 0x1b, 0xee, 0xc4, + 0xbd, 0xac, 0xf2, 0x89, 0xa3, 0xe9, 0x75, 0x1f, 0x9c, 0x5b, 0x03, 0xa6, + 0x47, 0x38, 0xe5, 0x1b, 0x8b, 0x94, 0xe8, 0x98, 0xe7, 0x11, 0x3c, 0xf3, + 0x3c, 0x8b, 0x3c, 0x3e, 0x7c, 0xa0, 0x37, 0xd1, 0x31, 0xe6, 0xb6, 0x39, + 0xb0, 0x34, 0x55, 0x25, 0xbd, 0x26, 0xb0, 0xb2, 0x51, 0x95, 0xdd, 0x0d, + 0x36, 0x7d, 0xaa, 0x5e, 0x7d, 0xd7, 0xd7, 0x61, 0x39, 0x2a, 0x43, 0x37, + 0x38, 0xac, 0xa9, 0x56, 0x35, 0x29, 0xf2, 0x79, 0xf4, 0x27, 0x7c, 0x1e, + 0xd5, 0xc9, 0x1d, 0xc8, 0x09, 0x36, 0x0b, 0x89, 0xce, 0x56, 0x61, 0x08, + 0xdb, 0x9a, 0xe8, 0x4c, 0xc1, 0x71, 0xa1, 0xf2, 0x66, 0x79, 0xbf, 0x94, + 0x8e, 0x7a, 0xab, 0xb9, 0x04, 0xd2, 0x6e, 0x42, 0x8b, 0xb5, 0x75, 0x24, + 0xe2, 0xef, 0x27, 0x28, 0x47, 0x05, 0xd4, 0xce, 0x28, 0xc7, 0xa1, 0x67, + 0xde, 0x34, 0xce, 0x04, 0xca, 0xcb, 0xd0, 0xfd, 0x46, 0x82, 0x9c, 0xba, + 0x36, 0xee, 0x17, 0xff, 0xe6, 0x3f, 0xa0, 0xa4, 0x45, 0x09, 0xa4, 0xae, + 0x81, 0x4c, 0x8e, 0xed, 0x5e, 0x8c, 0xbf, 0xa4, 0x9b, 0x7e, 0x29, 0x21, + 0x74, 0x7d, 0x9d, 0x2d, 0xf9, 0xbd, 0x04, 0x2d, 0x0e, 0xb4, 0x9d, 0xdf, + 0x18, 0x57, 0x85, 0x5a, 0xed, 0x80, 0x74, 0x54, 0x9b, 0xd5, 0xa1, 0x41, + 0x4c, 0xb6, 0xcc, 0x36, 0xbe, 0x36, 0x2b, 0x67, 0x9f, 0xc7, 0xa4, 0xce, + 0x4c, 0x51, 0x55, 0xeb, 0xad, 0x7a, 0xb5, 0xd9, 0x9b, 0xe1, 0x35, 0x75, + 0x3e, 0x62, 0x06, 0x5b, 0x3e, 0x4b, 0xd7, 0x92, 0xcd, 0x81, 0xba, 0xd4, + 0x46, 0xfe, 0x18, 0xd7, 0x03, 0xc7, 0x2c, 0x4b, 0xd4, 0xdf, 0x2f, 0x35, + 0x9d, 0xdd, 0x33, 0x3d, 0xeb, 0xf4, 0x1f, 0xc7, 0xe9, 0x55, 0xd5, 0x3a, + 0x33, 0xf2, 0x3a, 0xd9, 0xb3, 0x14, 0xf5, 0xc4, 0x31, 0xe5, 0xb6, 0x52, + 0xf5, 0x69, 0xc9, 0xa3, 0xf3, 0xfa, 0xbd, 0xf4, 0xcb, 0x92, 0xa9, 0x53, + 0x57, 0x49, 0x5d, 0xef, 0xa6, 0x77, 0x71, 0x64, 0xaa, 0x09, 0x31, 0xcd, + 0xfa, 0x96, 0x2c, 0x4f, 0x62, 0xba, 0xe0, 0x83, 0x4f, 0xd7, 0xd1, 0x2f, + 0x58, 0x14, 0xd7, 0x34, 0xbc, 0x67, 0x55, 0x32, 0xfc, 0xae, 0x0f, 0xfa, + 0xd7, 0x5f, 0x0d, 0x3f, 0x2a, 0x64, 0x1c, 0x87, 0x8e, 0x6a, 0xa8, 0xd6, + 0x21, 0x47, 0xa4, 0xf7, 0x63, 0x95, 0xb0, 0x27, 0xc0, 0xe1, 0x11, 0xb6, + 0xcf, 0xcc, 0xa8, 0x84, 0x4e, 0x2a, 0xcf, 0x28, 0x06, 0x00, 0x94, 0xfc, + 0xab, 0x93, 0xf9, 0x57, 0x7e, 0x30, 0xf8, 0x2f, 0xe5, 0x8a, 0x6b, 0x92, + 0xe1, 0xa1, 0x0f, 0xc6, 0xad, 0xff, 0x97, 0xfa, 0x46, 0xc3, 0x1f, 0xf9, + 0xe0, 0xb1, 0xaf, 0xc3, 0xff, 0xf7, 0xe7, 0x79, 0xfd, 0xa1, 0xff, 0x5f, + 0xcf, 0xf3, 0xfa, 0x43, 0xff, 0xd5, 0xf3, 0xbc, 0xee, 0x1b, 0x4c, 0x9e, + 0xe7, 0x45, 0xcb, 0xa9, 0x46, 0x8a, 0xa4, 0x67, 0xcf, 0x50, 0xfc, 0xfd, + 0xdf, 0x39, 0xcf, 0x8b, 0xe6, 0x4d, 0x7f, 0x59, 0xf5, 0x9a, 0xf1, 0x35, + 0xd4, 0x92, 0x0b, 0x2e, 0x6a, 0xeb, 0x91, 0xe6, 0x62, 0x1d, 0xc6, 0xd4, + 0xf7, 0xd3, 0x97, 0xe5, 0x5d, 0xaf, 0xde, 0x66, 0x5d, 0xaa, 0x56, 0x1d, + 0x57, 0xa4, 0x0d, 0x72, 0x22, 0x4a, 0x71, 0xcb, 0x72, 0xbe, 0x32, 0x68, + 0xa5, 0x8b, 0xa8, 0xbd, 0x6f, 0x84, 0x0d, 0x39, 0xdb, 0xb4, 0xdb, 0x32, + 0x1b, 0x6f, 0x2c, 0x50, 0xe5, 0xa6, 0x7e, 0x90, 0xbe, 0x1a, 0xd3, 0x8b, + 0xd6, 0x55, 0x98, 0x5e, 0x91, 0x44, 0xc7, 0x89, 0x7b, 0x15, 0xa6, 0x5f, + 0xad, 0xa4, 0xff, 0xd4, 0x0a, 0x8e, 0x8d, 0xf0, 0x70, 0x8e, 0xa8, 0x15, + 0x33, 0x1b, 0x6f, 0x9a, 0xa8, 0xba, 0xce, 0xba, 0xcc, 0xba, 0xf0, 0xc4, + 0x73, 0x95, 0xb6, 0x49, 0x95, 0xa7, 0x6d, 0x37, 0x64, 0xc3, 0x6b, 0x68, + 0x93, 0x74, 0x7a, 0x3e, 0xf7, 0xb8, 0x67, 0x96, 0x7a, 0xe9, 0x5c, 0xd4, + 0x7b, 0xe9, 0x6a, 0xa4, 0xd4, 0x2e, 0x2f, 0x38, 0x96, 0x0a, 0xf3, 0x66, + 0xde, 0x3e, 0xb3, 0xae, 0x72, 0x6e, 0x6a, 0xb1, 0x9c, 0x9a, 0xaa, 0x95, + 0xe9, 0xea, 0xbc, 0x02, 0xb3, 0x67, 0x66, 0xf5, 0x4c, 0x32, 0x3d, 0x35, + 0xb5, 0x5f, 0x5a, 0x0a, 0x9a, 0xe3, 0x49, 0x3e, 0x09, 0x13, 0x88, 0xec, + 0xd1, 0x79, 0x80, 0x4c, 0x4f, 0x39, 0xb1, 0x2b, 0xe7, 0x22, 0x72, 0xc9, + 0x4c, 0x75, 0xc6, 0xac, 0x1e, 0xad, 0x79, 0x56, 0xac, 0xf3, 0x94, 0xd6, + 0xe6, 0x33, 0x63, 0xbb, 0x4f, 0x69, 0x51, 0x43, 0x46, 0xf9, 0x78, 0x56, + 0x86, 0x09, 0x3d, 0x32, 0x72, 0x82, 0xf2, 0xdf, 0x69, 0x3d, 0xba, 0x3f, + 0x69, 0x8b, 0xbd, 0xd8, 0xdf, 0x93, 0xce, 0x49, 0xa7, 0xa2, 0x37, 0x4e, + 0x2a, 0x39, 0x6d, 0xbb, 0xd9, 0xa3, 0xc0, 0x04, 0x12, 0x29, 0xf8, 0xdc, + 0x93, 0xed, 0xb5, 0xc0, 0xab, 0x9e, 0x1c, 0xef, 0xf1, 0x71, 0x87, 0xa3, + 0x87, 0x2b, 0x6d, 0xd7, 0xe9, 0x4e, 0xdb, 0xae, 0x67, 0xe1, 0x65, 0x4f, + 0x2a, 0x74, 0x78, 0xfa, 0x3c, 0xd3, 0x66, 0x16, 0x7b, 0x9f, 0x8f, 0xde, + 0x78, 0x9d, 0xf1, 0xb4, 0x6d, 0x86, 0x47, 0x09, 0xa7, 0xb9, 0xfa, 0x3c, + 0xac, 0x57, 0x07, 0xbf, 0xf0, 0x18, 0xbd, 0x6f, 0x8c, 0xfb, 0x28, 0x6a, + 0x42, 0x4d, 0x0c, 0x0a, 0x76, 0x45, 0x93, 0x67, 0x64, 0x1b, 0x53, 0x93, + 0x98, 0xbd, 0x6c, 0x58, 0xaa, 0x5e, 0x9a, 0xca, 0x48, 0xf7, 0xe6, 0x7c, + 0x6a, 0x60, 0x71, 0x0c, 0x12, 0xbb, 0x5e, 0x4d, 0x71, 0xf9, 0x5c, 0x65, + 0x4e, 0xea, 0x7d, 0x79, 0x33, 0xd4, 0x3d, 0xd6, 0xe8, 0xbf, 0xa6, 0x70, + 0x10, 0xde, 0xaa, 0xa4, 0x78, 0xc8, 0xb3, 0x74, 0xd6, 0x53, 0x2f, 0x3f, + 0xda, 0xfe, 0x64, 0xfb, 0xfd, 0x5e, 0xad, 0xf1, 0xfb, 0xde, 0x31, 0xc6, + 0x35, 0xde, 0xc6, 0xf6, 0x80, 0xf7, 0x7a, 0x8e, 0x39, 0x8e, 0x63, 0x93, + 0x9d, 0xc1, 0xb9, 0xd8, 0x29, 0xa8, 0xfe, 0x7d, 0x6f, 0xe6, 0xa3, 0x95, + 0x5b, 0xdb, 0x23, 0xed, 0xf3, 0xbc, 0x46, 0x63, 0x9d, 0x37, 0xdf, 0xf8, + 0x88, 0xf7, 0xc7, 0xed, 0xdf, 0xf7, 0x36, 0x9b, 0x31, 0x55, 0xd1, 0xf5, + 0xec, 0x73, 0xe6, 0xb1, 0xec, 0x38, 0xe3, 0xf5, 0xdc, 0x7d, 0x33, 0xc9, + 0x6b, 0x9b, 0x30, 0xd5, 0xed, 0x5e, 0x16, 0x53, 0x59, 0x8d, 0x77, 0x61, + 0x59, 0x0b, 0xbd, 0x99, 0xa3, 0x65, 0x15, 0x70, 0x26, 0x36, 0xcb, 0xe8, + 0xe1, 0xea, 0x67, 0x4e, 0xe4, 0xee, 0x99, 0x09, 0xb6, 0xd9, 0x33, 0x35, + 0xaf, 0x6d, 0x6d, 0x0f, 0x63, 0x0a, 0xa3, 0xb1, 0xde, 0x9b, 0x69, 0xbc, + 0xc3, 0xbb, 0x0d, 0x73, 0x2e, 0xa1, 0xa9, 0xed, 0x7a, 0x76, 0x29, 0x67, + 0x66, 0x2d, 0x46, 0x3d, 0x57, 0x37, 0x73, 0x15, 0xf7, 0x2d, 0x25, 0x35, + 0xf7, 0x5a, 0x3f, 0xb3, 0x2e, 0x35, 0xc3, 0x1b, 0x63, 0x96, 0xa7, 0x9a, + 0xbc, 0x9f, 0x32, 0x86, 0x54, 0x95, 0xbc, 0x2a, 0xd9, 0x7f, 0x15, 0x99, + 0xb7, 0x8a, 0xd6, 0x07, 0xe1, 0x25, 0x21, 0xed, 0xd8, 0x2a, 0xd0, 0xd2, + 0x5e, 0x2c, 0x5a, 0x3b, 0x73, 0x59, 0xe5, 0x14, 0x6f, 0xb2, 0x1f, 0xad, + 0xea, 0xa3, 0xdc, 0x45, 0xad, 0x1d, 0x7b, 0x2f, 0xe5, 0x34, 0x71, 0xa3, + 0x55, 0xe0, 0x62, 0x51, 0xe3, 0xb9, 0x2d, 0x95, 0x48, 0xd5, 0xba, 0xcf, + 0xa3, 0xe7, 0x94, 0x9e, 0x24, 0xd7, 0x97, 0xa1, 0x2d, 0xf5, 0x31, 0x62, + 0x96, 0x9e, 0x91, 0x8d, 0x52, 0xf2, 0xdf, 0x30, 0x47, 0xa9, 0xf5, 0x5a, + 0xcc, 0x49, 0x68, 0xcd, 0x41, 0xd1, 0x57, 0xde, 0x49, 0xcb, 0xf2, 0xf4, + 0xab, 0x97, 0xfd, 0x39, 0xfd, 0x2b, 0xf3, 0xcb, 0xa8, 0x05, 0xdf, 0x86, + 0x29, 0xbf, 0x8f, 0x29, 0x55, 0x94, 0x13, 0xda, 0x3d, 0x33, 0x66, 0xa8, + 0x6e, 0xb6, 0xbe, 0x02, 0x2f, 0xcf, 0x22, 0x33, 0x36, 0xaa, 0x8f, 0x5a, + 0xab, 0x75, 0x93, 0xd6, 0x90, 0xeb, 0x1f, 0xd4, 0xed, 0x66, 0x9e, 0x48, + 0x2d, 0xf4, 0x3e, 0xe0, 0xfd, 0x34, 0xeb, 0x01, 0xef, 0x0b, 0x59, 0x64, + 0xca, 0x2a, 0xd3, 0x57, 0xaa, 0x07, 0xad, 0xc6, 0x97, 0xff, 0xc8, 0xdc, + 0x92, 0x3a, 0xc1, 0xbb, 0xaf, 0xfd, 0xa5, 0xf6, 0xc5, 0xde, 0xf1, 0xc6, + 0x87, 0xbd, 0x53, 0xb0, 0x37, 0x9e, 0x6b, 0x5f, 0xe9, 0xb5, 0x52, 0x3c, + 0x17, 0x14, 0xb0, 0x33, 0xcc, 0x39, 0x6c, 0xae, 0xf1, 0x39, 0xee, 0x7b, + 0x33, 0x0b, 0xcc, 0xab, 0x66, 0x42, 0x64, 0x67, 0xfb, 0xe1, 0xf6, 0x5a, + 0xef, 0x38, 0xec, 0x0d, 0xa7, 0xf1, 0x3b, 0xde, 0x66, 0xcc, 0xf5, 0x1c, + 0xc5, 0x9e, 0x23, 0x93, 0x7d, 0x9d, 0x73, 0xb0, 0xbc, 0x71, 0x3e, 0xf7, + 0xf0, 0x4c, 0xb2, 0x9b, 0xe6, 0x9f, 0x9f, 0x76, 0x8a, 0x18, 0xbc, 0xb3, + 0xc8, 0x5e, 0xcb, 0xa6, 0xf6, 0x76, 0xc4, 0xb2, 0x2a, 0x7b, 0x31, 0x4a, + 0xdf, 0xf5, 0xde, 0x1f, 0xa2, 0x9c, 0xfd, 0xcb, 0xb8, 0x63, 0x66, 0x18, + 0xff, 0xfd, 0x99, 0xd7, 0xb3, 0xa2, 0x79, 0x1c, 0x3b, 0xd6, 0xb8, 0x11, + 0x7b, 0x67, 0xfd, 0xd8, 0x4f, 0xb9, 0x2b, 0x04, 0x8a, 0x1a, 0xdd, 0x0f, + 0xcc, 0x3c, 0x90, 0xae, 0x91, 0x97, 0x42, 0x83, 0xe1, 0x43, 0xf5, 0x12, + 0x03, 0xe7, 0xd5, 0x1f, 0xbb, 0xae, 0x97, 0x75, 0xec, 0x9a, 0xa5, 0xc4, + 0x18, 0xf6, 0xab, 0x45, 0x0c, 0x2b, 0x3a, 0x4e, 0x7b, 0xa1, 0x80, 0x85, + 0x08, 0x11, 0x53, 0xe1, 0x4e, 0xef, 0x52, 0xab, 0xd7, 0x7b, 0xd1, 0xf2, + 0x44, 0xfb, 0x0f, 0xda, 0x1f, 0x40, 0xe8, 0xbe, 0xef, 0x55, 0x8d, 0x42, + 0xf7, 0xca, 0xd7, 0xd0, 0x95, 0xb3, 0x6e, 0xe3, 0x7c, 0xf3, 0xc3, 0x33, + 0xe7, 0x0b, 0xbb, 0x67, 0xc2, 0x04, 0x06, 0xf9, 0x22, 0x71, 0xdd, 0x3e, + 0xd3, 0xa3, 0xfb, 0x83, 0xd6, 0x84, 0xe3, 0x87, 0x39, 0x52, 0x57, 0xf9, + 0x57, 0x6d, 0xb3, 0x49, 0xe7, 0x3b, 0xc6, 0xe9, 0x7c, 0x11, 0x41, 0x75, + 0x2c, 0x53, 0xbd, 0x8d, 0x3b, 0x6a, 0x56, 0x56, 0x6e, 0x97, 0x92, 0x33, + 0xd3, 0x00, 0xfb, 0xcb, 0x6d, 0x56, 0x7f, 0x19, 0x1d, 0xc6, 0xbe, 0x1a, + 0xa1, 0xf2, 0xc7, 0x01, 0x1d, 0xb6, 0x72, 0x88, 0x99, 0xfa, 0x74, 0x80, + 0x3c, 0x15, 0x7d, 0x10, 0x33, 0xf6, 0xfd, 0x61, 0x5c, 0x04, 0xa5, 0x17, + 0x74, 0x76, 0x7b, 0x89, 0xfd, 0xa8, 0x76, 0xa6, 0x87, 0xc6, 0xa4, 0x8c, + 0x31, 0x9c, 0x30, 0x51, 0x6d, 0x31, 0xf6, 0xb3, 0xbe, 0xec, 0x6c, 0x32, + 0x19, 0x4e, 0x83, 0xfd, 0xbd, 0x71, 0xd9, 0x73, 0x6c, 0xb3, 0x93, 0xda, + 0x6a, 0xdd, 0xac, 0xc9, 0xd3, 0x8d, 0x27, 0x8c, 0xa5, 0xda, 0xd3, 0x2c, + 0xec, 0xf4, 0x34, 0x79, 0xe6, 0x0b, 0xb6, 0xf2, 0x13, 0x1e, 0x3b, 0xca, + 0x81, 0x6e, 0xef, 0x29, 0xfc, 0xb5, 0x95, 0x6b, 0x4f, 0x18, 0x2b, 0x77, + 0x29, 0xe1, 0x19, 0x33, 0x25, 0x8f, 0x0d, 0xc3, 0x74, 0x70, 0x74, 0x9c, + 0xad, 0x5c, 0x75, 0x82, 0x86, 0x99, 0x66, 0xa2, 0xa4, 0xc0, 0x51, 0x6a, + 0xea, 0xbc, 0x01, 0x39, 0x73, 0x0d, 0xcc, 0x4f, 0xcd, 0xf6, 0x1d, 0xb3, + 0x64, 0x9d, 0x4d, 0x94, 0xe6, 0x9d, 0x3e, 0xa6, 0x7e, 0x2f, 0xbd, 0x47, + 0x6b, 0xf1, 0xbe, 0x05, 0x9e, 0x74, 0x94, 0x3d, 0x06, 0x9d, 0xd7, 0xe4, + 0x5d, 0x02, 0xe4, 0x38, 0x91, 0x88, 0x2b, 0x38, 0xdb, 0xab, 0x1b, 0x3c, + 0x16, 0x9c, 0xcd, 0x48, 0x28, 0x6f, 0xb4, 0xc1, 0xd9, 0x06, 0x55, 0x66, + 0x16, 0x29, 0xef, 0x93, 0x85, 0x74, 0x6d, 0xe9, 0x97, 0x68, 0x79, 0xa3, + 0xfc, 0x76, 0xbc, 0x9b, 0x0e, 0x4c, 0x23, 0xd7, 0xa5, 0x0e, 0xce, 0x6e, + 0xa4, 0x77, 0x27, 0xd8, 0x0d, 0xf4, 0xcb, 0x51, 0x2f, 0x7d, 0xbf, 0x31, + 0x0e, 0xdf, 0xa8, 0x77, 0x6b, 0xd0, 0xc6, 0x00, 0xc7, 0x7b, 0xe3, 0x16, + 0xa2, 0xc4, 0xef, 0x42, 0xad, 0xc4, 0xd5, 0xc1, 0xcd, 0xd9, 0x67, 0x81, + 0x12, 0x95, 0x4c, 0xc0, 0x84, 0x34, 0x69, 0x9b, 0x3e, 0x67, 0x4c, 0xa6, + 0xcc, 0x1e, 0x23, 0xd3, 0x81, 0xab, 0x9e, 0x39, 0x27, 0x75, 0xe0, 0x78, + 0xc6, 0x9c, 0x7d, 0xa8, 0xd1, 0x50, 0xfc, 0xf6, 0x68, 0x8f, 0x72, 0xae, + 0xce, 0x63, 0xde, 0xf9, 0x74, 0x0d, 0xb5, 0xfd, 0xcb, 0xa8, 0xea, 0x44, + 0x32, 0xd5, 0xe0, 0xc9, 0x94, 0xf2, 0x59, 0xea, 0x2e, 0xc3, 0x5c, 0x75, + 0xb1, 0xf7, 0xa8, 0x61, 0x29, 0x20, 0x6d, 0x17, 0xf8, 0x67, 0xd6, 0xce, + 0x3c, 0x17, 0xed, 0x3d, 0x3e, 0x4b, 0xd7, 0x17, 0x2d, 0x67, 0x93, 0x7d, + 0x60, 0x48, 0xfd, 0x63, 0xfa, 0x82, 0x3c, 0x1c, 0x6b, 0x96, 0xf9, 0xd7, + 0x70, 0xfa, 0xf9, 0xc8, 0xb9, 0x17, 0xe4, 0xf4, 0x20, 0xe7, 0xce, 0x44, + 0x4e, 0xbf, 0x14, 0x6a, 0x93, 0x9c, 0x7e, 0x7a, 0xa6, 0x8a, 0x20, 0x5e, + 0xa8, 0x5c, 0xa7, 0xe3, 0xed, 0x76, 0xaf, 0xd7, 0x7b, 0x94, 0x7b, 0xbc, + 0x32, 0xc3, 0xb8, 0xa5, 0xdd, 0xe7, 0x35, 0xa1, 0x3d, 0x50, 0x8b, 0x14, + 0xd3, 0x88, 0xfc, 0xa6, 0xce, 0x9b, 0xc3, 0x5a, 0x91, 0x03, 0x99, 0x5e, + 0x5b, 0x34, 0x33, 0x8b, 0xcd, 0x34, 0x76, 0x71, 0xb7, 0xcf, 0xac, 0x9d, + 0x45, 0xf3, 0x5d, 0x9d, 0x03, 0xf1, 0x8f, 0xce, 0x81, 0x5c, 0x3d, 0xb3, + 0x91, 0xfa, 0xaf, 0x9e, 0xd9, 0x48, 0xdd, 0xa6, 0x0e, 0x26, 0xe6, 0x1a, + 0xa2, 0x33, 0x7b, 0x4c, 0x6c, 0xc2, 0xe8, 0xfb, 0x5a, 0xbf, 0xc4, 0x13, + 0x87, 0x55, 0x63, 0x5e, 0x95, 0x21, 0x10, 0xa9, 0x65, 0x55, 0x70, 0xb6, + 0xed, 0xf5, 0xbe, 0xa8, 0x4a, 0x99, 0x07, 0x1c, 0x89, 0xbf, 0xd1, 0xb7, + 0x77, 0x36, 0x4d, 0xc1, 0x8c, 0xa6, 0x18, 0x92, 0x16, 0xde, 0xeb, 0x79, + 0x9d, 0x9e, 0x32, 0x4b, 0xed, 0x4d, 0x7a, 0x0f, 0x08, 0x0b, 0xdb, 0x8e, + 0xa4, 0xdb, 0xc6, 0x41, 0x1a, 0x0c, 0xc7, 0xe7, 0x27, 0xc0, 0x4e, 0x9a, + 0xd2, 0x6d, 0xc3, 0xf1, 0x86, 0x04, 0x9d, 0x7f, 0x51, 0x3f, 0x25, 0x8d, + 0xd7, 0xee, 0xca, 0x01, 0x26, 0xac, 0x0a, 0xb3, 0x4f, 0x68, 0x9e, 0x9c, + 0xa1, 0x69, 0x03, 0xe6, 0xe0, 0x5f, 0x16, 0xc2, 0x24, 0x95, 0x5c, 0xb1, + 0xca, 0x29, 0x64, 0xca, 0x1e, 0xe5, 0x9b, 0xc6, 0xfb, 0x89, 0x44, 0xfc, + 0xb5, 0xc4, 0x0f, 0x04, 0x9d, 0x4c, 0x26, 0xab, 0x27, 0x7c, 0x72, 0x2a, + 0xdd, 0x46, 0x5a, 0x87, 0xe3, 0xb3, 0x13, 0xf4, 0xbc, 0x73, 0x28, 0xb8, + 0x18, 0x7d, 0x75, 0x55, 0x14, 0xf9, 0x52, 0x0a, 0xa8, 0xec, 0xdb, 0xbd, + 0x11, 0x2e, 0x03, 0x8c, 0xd3, 0x4c, 0x1d, 0x3a, 0xbf, 0x09, 0x74, 0x53, + 0x55, 0x7e, 0xd6, 0xc7, 0x4e, 0xcf, 0xf2, 0xab, 0x7c, 0x6c, 0x55, 0x24, + 0x90, 0x88, 0xff, 0x12, 0x61, 0x9a, 0xf1, 0x40, 0x72, 0x5e, 0xf1, 0xa6, + 0x07, 0xe8, 0xde, 0x1f, 0x4d, 0xb5, 0xa9, 0xa3, 0x55, 0x20, 0xc7, 0xe8, + 0xfd, 0x5d, 0xf4, 0xc6, 0xb6, 0x44, 0xbc, 0x47, 0x59, 0xbd, 0x81, 0xb6, + 0xbd, 0x8e, 0xb5, 0xa5, 0xd4, 0x20, 0xf2, 0x4b, 0x53, 0x24, 0x43, 0x8d, + 0x29, 0xd4, 0x22, 0xa8, 0x4f, 0x71, 0x36, 0x7d, 0x8d, 0xd7, 0x6b, 0x0a, + 0x74, 0x71, 0xc1, 0xd9, 0x56, 0x0b, 0xfd, 0x3a, 0x45, 0x9c, 0xfd, 0xdd, + 0x9c, 0xcb, 0xeb, 0x65, 0xab, 0xe8, 0x77, 0x17, 0x45, 0xb9, 0xb5, 0x80, + 0xed, 0xb5, 0x34, 0xb0, 0x3d, 0x87, 0x36, 0x3b, 0x3d, 0xe3, 0x18, 0x0a, + 0x6c, 0xca, 0xb9, 0xba, 0xde, 0x40, 0x31, 0xa0, 0x2e, 0xe6, 0x23, 0x93, + 0xad, 0xa1, 0x8b, 0xed, 0xc4, 0xdd, 0x26, 0x7c, 0x7e, 0x5a, 0x3f, 0x67, + 0x81, 0xb2, 0x26, 0x8d, 0x9e, 0x29, 0x6e, 0x72, 0x24, 0xec, 0xbd, 0x39, + 0xf4, 0x64, 0x6e, 0x1b, 0xd8, 0xd0, 0x9d, 0xe5, 0x4a, 0xc4, 0x0b, 0x13, + 0xc1, 0x4e, 0x5a, 0x9e, 0x6c, 0xb9, 0x7a, 0x5e, 0xf2, 0x58, 0x78, 0x37, + 0x40, 0xcf, 0xdd, 0x2f, 0xa7, 0x7a, 0x89, 0xfd, 0x02, 0x6a, 0x77, 0xc9, + 0xd9, 0xda, 0xae, 0x06, 0xfa, 0x95, 0x61, 0xdd, 0x2b, 0xcc, 0xd7, 0x5f, + 0xd8, 0xf8, 0x3a, 0x7a, 0x0f, 0xd7, 0x8c, 0xa1, 0xf3, 0x0d, 0xfc, 0xf2, + 0xe4, 0x37, 0xaa, 0x0c, 0xff, 0x16, 0x65, 0xee, 0x9e, 0x9e, 0x61, 0xbc, + 0x30, 0x44, 0x67, 0x47, 0xe9, 0xce, 0x2c, 0x5a, 0x36, 0xe3, 0xe3, 0x42, + 0x9e, 0xd1, 0x33, 0x8d, 0xa9, 0x1f, 0xe9, 0x26, 0xa4, 0xec, 0xa5, 0xb0, + 0xd2, 0xfb, 0xff, 0x72, 0x6e, 0x55, 0x43, 0x59, 0x08, 0x4a, 0x5c, 0xf2, + 0x02, 0x87, 0x05, 0xf5, 0xa2, 0xd3, 0x23, 0xe6, 0x39, 0x36, 0xec, 0xfd, + 0x4f, 0x86, 0x38, 0x5f, 0x8e, 0x9f, 0x9b, 0x43, 0x6f, 0xb4, 0x24, 0xb1, + 0x9e, 0x61, 0x5a, 0x9f, 0x67, 0x68, 0x8c, 0x6f, 0xec, 0x6d, 0x39, 0xfe, + 0xb1, 0x3e, 0x3a, 0x23, 0x3e, 0x15, 0xe8, 0x7a, 0xee, 0x6c, 0xd4, 0xaa, + 0x92, 0x58, 0xf8, 0x76, 0x42, 0x85, 0x10, 0x57, 0x84, 0xc8, 0xe4, 0x24, + 0x06, 0xbe, 0x38, 0x4d, 0xef, 0x75, 0xdb, 0x9c, 0xa0, 0xbf, 0xf7, 0x25, + 0x08, 0xef, 0x0e, 0x12, 0x1b, 0x9d, 0x4b, 0xa4, 0xf5, 0x52, 0x38, 0xfe, + 0x98, 0x09, 0xb6, 0xec, 0x2c, 0x6c, 0x3b, 0xd2, 0x29, 0x47, 0xbf, 0x21, + 0x8d, 0xae, 0x05, 0xa7, 0xf8, 0xcd, 0xc7, 0x56, 0x7b, 0x42, 0xcc, 0x54, + 0x55, 0x31, 0xd7, 0x6d, 0xf6, 0x59, 0x42, 0xba, 0xd8, 0xba, 0x01, 0xc6, + 0x92, 0x3e, 0x8e, 0x20, 0x15, 0x58, 0x82, 0x96, 0x50, 0x35, 0x47, 0xdf, + 0xe0, 0x58, 0x1c, 0x64, 0xed, 0x96, 0xd0, 0x76, 0x2f, 0xdb, 0x7b, 0x4c, + 0xab, 0x3d, 0xc9, 0x3a, 0xcc, 0x21, 0x03, 0x86, 0xdb, 0x21, 0x0b, 0xfd, + 0xff, 0x3c, 0x91, 0xdf, 0x39, 0x5f, 0x3b, 0x74, 0x92, 0xa6, 0x20, 0xfb, + 0x95, 0xf4, 0x76, 0xa3, 0x23, 0x11, 0x6f, 0x18, 0x59, 0x5e, 0xc9, 0x87, + 0xc8, 0x81, 0xac, 0xb5, 0x6a, 0x7e, 0xc1, 0x5a, 0x95, 0x8f, 0x43, 0xda, + 0x99, 0x93, 0xf8, 0x30, 0x4a, 0x61, 0xa2, 0x70, 0x6c, 0xec, 0xd0, 0x40, + 0x2a, 0x64, 0x03, 0x4d, 0x4d, 0xf6, 0x27, 0xe2, 0xb7, 0x8f, 0xac, 0xa8, + 0xb4, 0x03, 0xd9, 0x9f, 0xb7, 0xf6, 0xee, 0xb5, 0x89, 0x78, 0x7b, 0x62, + 0x63, 0x27, 0x9d, 0x1d, 0x24, 0x87, 0xb5, 0x48, 0xf7, 0x63, 0x94, 0x54, + 0xb4, 0xf5, 0x37, 0x8f, 0x10, 0x9e, 0x7e, 0x43, 0x1a, 0x1f, 0xac, 0x0f, + 0x16, 0x61, 0xba, 0x3d, 0xca, 0xca, 0x95, 0xfc, 0x8e, 0x6c, 0x58, 0x81, + 0x5c, 0xe9, 0x74, 0xe3, 0x8a, 0xca, 0xe5, 0x95, 0xdc, 0x5a, 0x0d, 0xcf, + 0xec, 0x5f, 0xb0, 0x56, 0xe7, 0xa0, 0x6b, 0xae, 0x68, 0x99, 0x74, 0x9d, + 0x4e, 0x7e, 0x27, 0x9d, 0xf5, 0x53, 0x1d, 0xa6, 0xb5, 0x42, 0x33, 0x6a, + 0xb6, 0x0e, 0xe3, 0x21, 0x4a, 0x37, 0xf9, 0xa1, 0x44, 0x3c, 0x6b, 0x44, + 0xcb, 0xd7, 0x07, 0x41, 0x9c, 0x06, 0xea, 0x30, 0x11, 0x6d, 0x50, 0x14, + 0x2c, 0x5c, 0x5b, 0x8f, 0xa5, 0xaf, 0x49, 0x28, 0x7b, 0x79, 0x20, 0x88, + 0x7a, 0xef, 0x76, 0x7a, 0xb7, 0x22, 0x58, 0x04, 0x6a, 0x81, 0x04, 0x3b, + 0x35, 0x3e, 0x1b, 0xb4, 0x86, 0xe8, 0xdd, 0x8c, 0x50, 0xfc, 0x95, 0x64, + 0x57, 0xee, 0xd6, 0x1b, 0x19, 0xf9, 0x3c, 0x9a, 0xec, 0xfb, 0xb8, 0x32, + 0x57, 0x9c, 0x0f, 0x50, 0x48, 0x9a, 0x89, 0x78, 0x48, 0x20, 0x67, 0x88, + 0x4d, 0xd5, 0x5b, 0x1f, 0x52, 0xd3, 0xfd, 0x00, 0xb6, 0x91, 0xce, 0x0b, + 0x21, 0xd4, 0x2d, 0xd3, 0x5f, 0x15, 0xfa, 0xe4, 0xe4, 0x9d, 0x1c, 0xef, + 0x27, 0xa0, 0xf8, 0x73, 0xa9, 0x2d, 0x74, 0x5a, 0x4f, 0x4a, 0xd5, 0xb2, + 0x3e, 0x92, 0x15, 0x44, 0xcc, 0x4d, 0xb9, 0xc8, 0xf5, 0x46, 0x75, 0x91, + 0xbe, 0x28, 0x9d, 0x4f, 0xde, 0x58, 0x60, 0xf4, 0xd4, 0xc3, 0x98, 0x39, + 0x47, 0xf5, 0x17, 0xb9, 0xa5, 0x9c, 0x6b, 0xf2, 0x85, 0x50, 0x8f, 0xf6, + 0x6c, 0x3a, 0x38, 0xf3, 0xe4, 0x0b, 0xa1, 0x25, 0xda, 0x0f, 0xd0, 0x35, + 0xa6, 0x87, 0xd8, 0xd3, 0x6e, 0xad, 0x16, 0x5c, 0x01, 0x5d, 0x6c, 0x63, + 0xff, 0xd5, 0x78, 0xa3, 0x12, 0xcf, 0x9e, 0x60, 0x91, 0x57, 0x9c, 0x0f, + 0x65, 0x79, 0x2f, 0x04, 0x69, 0xfc, 0x0d, 0xfd, 0x74, 0x8e, 0xff, 0x26, + 0xc0, 0xb2, 0x0b, 0xfb, 0x47, 0x61, 0x56, 0x68, 0xa4, 0x23, 0x15, 0x88, + 0x3d, 0x7d, 0x4e, 0xb5, 0x60, 0xc3, 0x54, 0x77, 0xf5, 0x6f, 0xb4, 0x97, + 0x78, 0x7c, 0x60, 0xac, 0xfe, 0x54, 0x7f, 0x94, 0xab, 0x36, 0xbb, 0xca, + 0xde, 0x0b, 0x41, 0x61, 0x8f, 0x56, 0x77, 0xe2, 0x3d, 0x2c, 0x93, 0x96, + 0xae, 0x3a, 0xcd, 0x3a, 0xde, 0x0b, 0x85, 0xbd, 0xef, 0x05, 0x69, 0x7a, + 0x63, 0x3f, 0xfd, 0x0e, 0x43, 0xcb, 0x49, 0x8e, 0x35, 0x0d, 0x6c, 0xb4, + 0xa5, 0xcd, 0xd1, 0x79, 0x3c, 0xf0, 0x27, 0x7d, 0x01, 0xb7, 0xd4, 0xec, + 0x9a, 0x7c, 0x29, 0x04, 0xb6, 0x4f, 0xb5, 0xe9, 0x27, 0x48, 0x61, 0x6f, + 0xa8, 0xd8, 0xdb, 0x1b, 0xa4, 0x77, 0x68, 0x3e, 0x34, 0x42, 0x6f, 0x14, + 0x62, 0x1d, 0x17, 0x42, 0x87, 0x10, 0xba, 0x0b, 0x58, 0xda, 0x85, 0x60, + 0xb0, 0x33, 0x09, 0xd3, 0x46, 0xde, 0xd4, 0x91, 0xe2, 0x31, 0xcc, 0x59, + 0x02, 0x17, 0xb9, 0x3f, 0xe8, 0x9f, 0x53, 0xda, 0x2d, 0x6a, 0xf5, 0x27, + 0x48, 0x6c, 0xf5, 0x08, 0xc3, 0x27, 0xdb, 0x43, 0x46, 0xdf, 0xa6, 0xff, + 0x75, 0x9e, 0x93, 0x4a, 0x1e, 0x47, 0xb2, 0xfc, 0x0b, 0x21, 0x32, 0x3d, + 0x7c, 0x6d, 0x1e, 0xc7, 0x7b, 0x7a, 0x83, 0x87, 0xad, 0x9e, 0x0f, 0xa8, + 0x03, 0x70, 0xae, 0xb2, 0x77, 0x43, 0xc9, 0xd3, 0xc9, 0x69, 0x1c, 0xbd, + 0x7f, 0x10, 0x62, 0x1b, 0xe8, 0x9d, 0x0b, 0xf2, 0x13, 0xe7, 0x5f, 0xf7, + 0xe5, 0x06, 0xfe, 0x3e, 0xca, 0x27, 0xbe, 0xf9, 0x12, 0xaf, 0x3d, 0xec, + 0xac, 0x4b, 0xd2, 0xc0, 0x97, 0xfd, 0x1f, 0x35, 0x38, 0xff, 0x85, 0x57, + 0x6c, 0x45, 0xfd, 0x60, 0xc3, 0x79, 0x7f, 0x88, 0x4c, 0xd5, 0x16, 0x7f, + 0xd0, 0xad, 0x8b, 0xed, 0x44, 0xfd, 0x21, 0x03, 0x56, 0x30, 0x1e, 0xe6, + 0x36, 0x26, 0x07, 0xcc, 0xcc, 0x2a, 0xc6, 0x86, 0x14, 0xf8, 0xf8, 0x30, + 0xc4, 0x3e, 0x1c, 0x70, 0x6c, 0xd8, 0xef, 0x8b, 0x04, 0xff, 0x18, 0xa5, + 0x21, 0x5b, 0x30, 0xe4, 0x83, 0x81, 0xe7, 0x91, 0x07, 0xbc, 0xad, 0xec, + 0x21, 0x79, 0x23, 0x4a, 0x6c, 0x7b, 0xe7, 0xb2, 0x76, 0x67, 0x68, 0x7c, + 0x48, 0xe5, 0x75, 0x06, 0x9d, 0xe0, 0x76, 0x5b, 0x42, 0xfe, 0xa2, 0xcd, + 0xca, 0x48, 0xa5, 0xe3, 0xce, 0x09, 0x93, 0x31, 0x24, 0xe9, 0x07, 0x9b, + 0x32, 0x12, 0x63, 0xef, 0x0e, 0xf0, 0x1b, 0x2c, 0x50, 0xee, 0x81, 0xe6, + 0x76, 0x61, 0xbc, 0xe4, 0x29, 0x35, 0xca, 0x3b, 0xab, 0xa0, 0xd8, 0x21, + 0x41, 0xec, 0xd5, 0x01, 0xba, 0x07, 0x48, 0x77, 0x50, 0xd9, 0x2d, 0x52, + 0xdc, 0x2c, 0x73, 0xbd, 0x3d, 0x9a, 0x9e, 0x34, 0x12, 0xa6, 0xf7, 0x7c, + 0x2d, 0x38, 0xc7, 0xe0, 0x6f, 0xe8, 0x1c, 0x38, 0x53, 0x65, 0x10, 0x6d, + 0xce, 0x6c, 0x99, 0xff, 0x6e, 0xba, 0x53, 0xdb, 0xfd, 0x31, 0xd7, 0x8d, + 0x90, 0x8d, 0x1d, 0xd6, 0x1d, 0x24, 0x79, 0x20, 0x6d, 0x3c, 0xa7, 0x3d, + 0x6c, 0x0b, 0xd1, 0x6f, 0xed, 0x3f, 0x1b, 0x6e, 0xb4, 0xdb, 0x70, 0x34, + 0xb4, 0x0d, 0xaf, 0x8e, 0xd2, 0xdb, 0x77, 0x3f, 0x97, 0xfd, 0x1b, 0xf4, + 0xc5, 0xff, 0xc0, 0xd6, 0x0a, 0x7d, 0xf9, 0x64, 0x1c, 0xf9, 0x2c, 0x91, + 0x86, 0x8f, 0x01, 0x7e, 0x01, 0x9f, 0x25, 0xc6, 0x42, 0x0e, 0xe8, 0xf6, + 0x43, 0x6c, 0xd3, 0xc0, 0x54, 0x78, 0x76, 0x03, 0x89, 0x65, 0x0d, 0x33, + 0x7c, 0x29, 0xf6, 0xa0, 0x33, 0x38, 0x2f, 0xaa, 0x39, 0xb8, 0x22, 0xc4, + 0x94, 0x67, 0x61, 0x9f, 0xa6, 0x9e, 0x6b, 0xdb, 0x00, 0xe1, 0x15, 0x21, + 0x88, 0x44, 0x84, 0x29, 0x12, 0xbe, 0x9d, 0x5a, 0x89, 0xee, 0x58, 0xba, + 0x6b, 0xf8, 0x70, 0x68, 0x2a, 0x8e, 0x98, 0x2f, 0x86, 0x0e, 0x07, 0x69, + 0x4d, 0xe3, 0xa5, 0x85, 0x79, 0x5d, 0xed, 0xc3, 0xf1, 0x50, 0x3f, 0x14, + 0xff, 0x52, 0xf2, 0x86, 0x54, 0x61, 0xc6, 0xf9, 0x92, 0x4c, 0xec, 0x2c, + 0xbc, 0xb9, 0x41, 0x3f, 0x39, 0x9c, 0x31, 0x3f, 0x03, 0x69, 0xc1, 0x93, + 0x49, 0x96, 0x90, 0x2c, 0x6f, 0x69, 0xe8, 0xba, 0xb2, 0xed, 0x5e, 0x5a, + 0xd3, 0x5b, 0xa1, 0xcd, 0x21, 0xba, 0xa6, 0xff, 0x2d, 0x8e, 0x0d, 0xb3, + 0x62, 0x9b, 0x60, 0xec, 0x9e, 0xfb, 0xf5, 0x1e, 0xa3, 0xd9, 0x3e, 0x88, + 0x2c, 0x0e, 0x22, 0x66, 0x0e, 0x40, 0xec, 0x42, 0xbf, 0x26, 0x4a, 0x1c, + 0xf5, 0x21, 0xd2, 0x9c, 0x42, 0xef, 0x86, 0x0a, 0x91, 0x30, 0x1f, 0xba, + 0xc8, 0xd5, 0x87, 0x58, 0xe7, 0x26, 0x19, 0x8a, 0x58, 0xd1, 0x6a, 0x15, + 0xdb, 0xd5, 0xe1, 0x19, 0x3e, 0x6b, 0x88, 0xb8, 0x5f, 0x12, 0xe0, 0xf4, + 0x83, 0x51, 0x3a, 0x9a, 0x7f, 0x30, 0xa4, 0x06, 0xe5, 0xf6, 0x93, 0xc8, + 0x21, 0xe4, 0xd4, 0x4c, 0x93, 0xae, 0xb8, 0xf4, 0x94, 0x5a, 0xdc, 0x22, + 0x8c, 0x3f, 0x4e, 0x44, 0xe2, 0x54, 0xcb, 0x93, 0x7d, 0x07, 0x03, 0x11, + 0x81, 0xc8, 0x2a, 0x91, 0x84, 0xc1, 0xe1, 0xac, 0x22, 0x62, 0x44, 0x48, + 0x95, 0xdd, 0x98, 0x87, 0x89, 0x64, 0xb9, 0xe8, 0x5e, 0x34, 0x46, 0xbc, + 0xc8, 0x95, 0x28, 0xa5, 0xee, 0x11, 0x7e, 0x7e, 0xd6, 0x17, 0x6d, 0x0b, + 0xd1, 0xd5, 0xd8, 0x6f, 0x71, 0xa7, 0x42, 0x89, 0x12, 0x90, 0xbc, 0x51, + 0x52, 0xfe, 0xb7, 0xe0, 0xb1, 0xf6, 0xf3, 0x51, 0x72, 0xfd, 0x57, 0xed, + 0xaf, 0x47, 0x2f, 0x6c, 0xb5, 0x18, 0xe6, 0xe5, 0xf5, 0xb4, 0xa7, 0x15, + 0xc3, 0xa9, 0x29, 0x51, 0x6d, 0x6c, 0x6b, 0x22, 0x1d, 0x0a, 0x60, 0x16, + 0x4c, 0x4e, 0x4c, 0x4e, 0xcc, 0x45, 0x17, 0x7d, 0x7f, 0xf3, 0xcf, 0xc1, + 0x50, 0xfc, 0xee, 0x44, 0x26, 0xcf, 0x40, 0xb2, 0x8d, 0x5b, 0xfa, 0x13, + 0x97, 0x4d, 0xca, 0x4a, 0xe7, 0x71, 0xf4, 0xfc, 0xf1, 0xd7, 0x19, 0x38, + 0x1e, 0xda, 0x19, 0xa2, 0x3b, 0x21, 0x3e, 0x8b, 0x32, 0xa5, 0x63, 0x64, + 0x0e, 0xb5, 0x8e, 0xa3, 0x7d, 0x4c, 0xde, 0x15, 0x59, 0x1b, 0xe5, 0x46, + 0xc7, 0xf6, 0xb5, 0xeb, 0x6a, 0xa9, 0x3c, 0xb9, 0xe9, 0xd1, 0xe4, 0x5a, + 0xdb, 0x47, 0x6b, 0xe8, 0x1a, 0xaf, 0x2b, 0x97, 0x39, 0x45, 0x66, 0x5d, + 0x8c, 0x72, 0x60, 0xdf, 0x36, 0x1c, 0xaf, 0x1c, 0x60, 0xf2, 0x40, 0xfe, + 0xf0, 0xb2, 0x2a, 0xf4, 0x4e, 0xf4, 0x7b, 0x4a, 0x4d, 0xe7, 0x2f, 0xd3, + 0xf8, 0x2b, 0x08, 0x39, 0x52, 0x9b, 0xd4, 0x73, 0xb9, 0x34, 0xa4, 0x75, + 0xd3, 0x7e, 0xf1, 0x8e, 0x86, 0x1c, 0xbb, 0xac, 0x73, 0x38, 0x71, 0xa4, + 0x7e, 0x19, 0x25, 0x48, 0xef, 0x9a, 0x83, 0x0b, 0xf5, 0x3a, 0x4f, 0xab, + 0x8e, 0xe1, 0xcd, 0x1e, 0xa6, 0x9c, 0x78, 0x33, 0x1a, 0x93, 0x90, 0x17, + 0xf5, 0xdf, 0x70, 0x99, 0xd2, 0x25, 0x9c, 0xfa, 0xcd, 0xe5, 0x24, 0x65, + 0x1e, 0x1d, 0x44, 0xba, 0x94, 0x5f, 0xba, 0x4c, 0xe9, 0x3a, 0x11, 0xd7, + 0x0d, 0xd1, 0x99, 0xfc, 0xc2, 0xcb, 0xfc, 0x86, 0x5c, 0x98, 0xe2, 0x71, + 0x0b, 0x20, 0xfd, 0xf4, 0x72, 0xfd, 0x06, 0x43, 0x05, 0xd6, 0x70, 0xea, + 0xd9, 0xcb, 0x74, 0x4e, 0x62, 0x5a, 0x3f, 0xfa, 0xb1, 0x3e, 0x6d, 0x54, + 0x73, 0x28, 0x92, 0x33, 0x26, 0xf8, 0xe6, 0xe5, 0x20, 0x5f, 0xf4, 0xdd, + 0x3c, 0x4c, 0xb9, 0xf3, 0x72, 0xba, 0xdb, 0xed, 0x59, 0x02, 0x9f, 0xeb, + 0x3f, 0xe6, 0x44, 0xae, 0xfb, 0x91, 0x44, 0x5c, 0x1c, 0x04, 0x91, 0x69, + 0x52, 0x56, 0x3c, 0x21, 0x27, 0xd8, 0x74, 0x99, 0x60, 0x1d, 0x94, 0x12, + 0x4f, 0x0e, 0x7e, 0x07, 0x4b, 0x25, 0xad, 0x16, 0xd8, 0xee, 0x25, 0xa8, + 0xe7, 0xd0, 0x39, 0xe8, 0x75, 0x97, 0xcb, 0x80, 0xc6, 0x1d, 0x1f, 0xa6, + 0xe5, 0x9a, 0x1a, 0x89, 0xf8, 0x7c, 0xf4, 0xfc, 0x56, 0xba, 0x5e, 0x86, + 0x86, 0xd3, 0x1b, 0xac, 0x13, 0xf1, 0x43, 0xc3, 0x0c, 0x5d, 0x95, 0x26, + 0x9f, 0xbc, 0x64, 0x1e, 0x2d, 0xe9, 0xc8, 0xe0, 0xe4, 0x29, 0x74, 0xed, + 0xe4, 0x67, 0x7d, 0x4e, 0xe4, 0xde, 0x70, 0xf2, 0xdd, 0x4b, 0xaf, 0x5e, + 0x4e, 0xc4, 0xbf, 0x37, 0xfc, 0x51, 0x74, 0xa3, 0xad, 0x70, 0xc3, 0x75, + 0xbe, 0x62, 0xcf, 0x4c, 0xf8, 0x48, 0xbf, 0x04, 0xe1, 0xb1, 0x00, 0x29, + 0x72, 0x95, 0xcb, 0xa1, 0x5f, 0x78, 0xe5, 0xa0, 0x1c, 0x52, 0x5d, 0x4f, + 0xdf, 0x94, 0x8b, 0x96, 0x40, 0xdd, 0x06, 0x5b, 0xa8, 0x0d, 0xb5, 0x9b, + 0xde, 0xbe, 0x03, 0x97, 0x28, 0xd4, 0x9e, 0x41, 0x55, 0xde, 0x74, 0x29, + 0xaf, 0xe1, 0x6a, 0xcc, 0x91, 0xd9, 0x4f, 0x5f, 0xca, 0x45, 0x49, 0x7f, + 0x4c, 0x0b, 0x27, 0x5a, 0x2e, 0x59, 0x95, 0xfe, 0xda, 0x75, 0x89, 0x0b, + 0x01, 0xf2, 0x3b, 0xda, 0x27, 0x3f, 0xbe, 0x34, 0x06, 0xe9, 0x0e, 0x6b, + 0x3f, 0xb1, 0x0d, 0x5d, 0x14, 0xbe, 0xc7, 0x2e, 0xd1, 0xf0, 0xcd, 0x97, + 0xe8, 0x1a, 0x57, 0xf3, 0xa0, 0xb7, 0x81, 0x8e, 0x13, 0x5b, 0xa8, 0x65, + 0x36, 0x99, 0xf2, 0x69, 0x7b, 0xaa, 0x42, 0xa3, 0x87, 0x84, 0xd8, 0xe9, + 0x75, 0x97, 0xa0, 0x30, 0x1e, 0xad, 0x57, 0xee, 0xa2, 0x5c, 0x79, 0x69, + 0x2f, 0xd2, 0x7d, 0xc3, 0xa5, 0x14, 0x65, 0x6d, 0xd7, 0x55, 0x3a, 0xb9, + 0x96, 0x6e, 0x24, 0x45, 0x3e, 0x64, 0xf9, 0x34, 0x70, 0x6a, 0x5b, 0xcb, + 0x36, 0xc1, 0x32, 0x26, 0xa7, 0xb9, 0xdd, 0x53, 0x0a, 0xa7, 0x3c, 0x85, + 0x96, 0xd0, 0x0b, 0xed, 0x1b, 0x4b, 0xd3, 0x4e, 0x6d, 0x15, 0x32, 0x24, + 0xe3, 0x9c, 0x52, 0x68, 0x0d, 0x50, 0xa9, 0x5f, 0x3d, 0xd0, 0x68, 0xa7, + 0x6b, 0x8f, 0xe8, 0xe8, 0x3a, 0x3e, 0x14, 0xec, 0xdc, 0x2a, 0xb0, 0x32, + 0xdd, 0xdd, 0xf7, 0x65, 0xb4, 0xd1, 0x3e, 0x18, 0x45, 0x0e, 0x54, 0x13, + 0x8b, 0xb6, 0x64, 0x80, 0xed, 0x04, 0xea, 0x3a, 0xd5, 0xed, 0x47, 0xbd, + 0xf4, 0x66, 0x97, 0xa3, 0xe9, 0x16, 0x38, 0x8a, 0xba, 0xe8, 0xab, 0x43, + 0x74, 0x05, 0x83, 0x16, 0xf5, 0x2f, 0x9d, 0x23, 0xb9, 0xee, 0xc7, 0x31, + 0x00, 0x7c, 0x31, 0x5c, 0xf1, 0xdb, 0x43, 0x2f, 0xf9, 0xe9, 0x5e, 0xd1, + 0x60, 0x27, 0xcd, 0x1b, 0xef, 0xc8, 0xba, 0x6d, 0x0c, 0x68, 0x30, 0xd5, + 0x54, 0x7a, 0xa7, 0x46, 0x38, 0x11, 0x4f, 0xc3, 0x74, 0x9d, 0xfe, 0xc1, + 0x4d, 0x17, 0x36, 0xec, 0xdb, 0x60, 0x65, 0x48, 0x6b, 0x96, 0xd7, 0x92, + 0xb3, 0x43, 0x20, 0xa7, 0x96, 0x57, 0x36, 0x6f, 0xdd, 0xd9, 0xfe, 0x9b, + 0x4d, 0x94, 0x27, 0x41, 0x09, 0x91, 0x8a, 0xf3, 0xe8, 0xde, 0xc9, 0x44, + 0xfc, 0xc9, 0x04, 0xbd, 0x9f, 0xc7, 0x1e, 0xa2, 0xe7, 0x74, 0xf7, 0x2b, + 0xf0, 0x98, 0x3a, 0xb2, 0x51, 0x37, 0x65, 0x50, 0xdf, 0x3b, 0xaf, 0xac, + 0xd5, 0xa1, 0x61, 0xa8, 0x17, 0xd6, 0x52, 0xbd, 0x30, 0x19, 0xaf, 0x9e, + 0x83, 0x74, 0xa4, 0x68, 0x36, 0x7f, 0xed, 0x07, 0xbe, 0xcd, 0x7f, 0xc1, + 0x7f, 0x35, 0x5d, 0xb0, 0xa3, 0x70, 0x4e, 0x1e, 0xf0, 0xa8, 0x75, 0x9c, + 0xd6, 0x1f, 0xd5, 0x6f, 0x17, 0xb2, 0x50, 0x73, 0xf8, 0x81, 0x30, 0x41, + 0xb6, 0xf9, 0xe8, 0xde, 0xfe, 0xa4, 0xb4, 0xf9, 0xf5, 0x00, 0xdf, 0x40, + 0x6c, 0xe0, 0xb4, 0x4b, 0xf4, 0x4b, 0x28, 0xd5, 0x8d, 0x89, 0xcd, 0xda, + 0xbb, 0xd1, 0x49, 0x6f, 0x77, 0xe5, 0xf2, 0xc6, 0x4a, 0xe5, 0x30, 0xb6, + 0x3a, 0x11, 0x3f, 0xd8, 0xbf, 0x2f, 0x70, 0x61, 0x5b, 0xb3, 0x59, 0x34, + 0xef, 0xf3, 0x9f, 0xdf, 0x2a, 0xb6, 0x5f, 0xd8, 0x84, 0xdc, 0x47, 0x9a, + 0x31, 0x69, 0x4c, 0x37, 0x5d, 0xc1, 0xc7, 0xca, 0xc5, 0x0a, 0xcc, 0xf5, + 0x88, 0x07, 0x82, 0x58, 0x56, 0x4a, 0xc9, 0xa3, 0xdf, 0x39, 0x09, 0xca, + 0x08, 0xba, 0x83, 0x8f, 0xc4, 0x7e, 0x39, 0x70, 0x2c, 0x4a, 0xfb, 0xbf, + 0x30, 0xf1, 0x89, 0xd2, 0xae, 0x2f, 0x9f, 0x04, 0x13, 0xc5, 0x35, 0xd5, + 0xa7, 0x4d, 0x53, 0x58, 0x65, 0x7e, 0x6f, 0xf9, 0xc8, 0x8c, 0xe2, 0xcc, + 0x53, 0x60, 0x3b, 0x87, 0x65, 0xfd, 0x6c, 0x10, 0x8a, 0x8d, 0x12, 0x0d, + 0xfd, 0xce, 0xc8, 0xb9, 0xd0, 0x8c, 0x62, 0xed, 0xa9, 0x27, 0x79, 0x11, + 0xce, 0x73, 0x60, 0xf3, 0xf0, 0x89, 0xf8, 0xe7, 0x83, 0xf4, 0x34, 0xf6, + 0x44, 0xfc, 0xdd, 0xc1, 0x01, 0xe5, 0xbe, 0x02, 0xba, 0x1a, 0x62, 0xe1, + 0x80, 0xf2, 0x85, 0xc9, 0x66, 0xea, 0x4c, 0xc4, 0x17, 0xa3, 0xbb, 0x5f, + 0x7e, 0xc5, 0x46, 0xf8, 0x46, 0x98, 0xe5, 0x65, 0xaa, 0xd0, 0xd4, 0xdd, + 0xc0, 0x79, 0xfe, 0x89, 0x7a, 0x4a, 0x17, 0xea, 0xac, 0xaf, 0x60, 0x49, + 0x0b, 0xbd, 0x74, 0x7f, 0x98, 0xc9, 0xd5, 0xc5, 0x41, 0x6c, 0x2c, 0xdd, + 0xeb, 0x4c, 0xf7, 0x48, 0x77, 0xbc, 0x52, 0xf0, 0x1c, 0xa6, 0xb7, 0x81, + 0xe6, 0x56, 0x93, 0x0b, 0x2d, 0x3b, 0x33, 0xc4, 0xaa, 0x47, 0xd4, 0xb0, + 0xd7, 0x4c, 0xd7, 0x88, 0x52, 0xcd, 0xe4, 0x3f, 0xe7, 0xbf, 0x71, 0x34, + 0x7f, 0x5c, 0x81, 0x23, 0x7b, 0x14, 0x8e, 0x11, 0x84, 0x63, 0xec, 0x80, + 0x3a, 0x8f, 0xc2, 0x41, 0xa1, 0x28, 0x82, 0xec, 0xdb, 0x26, 0x5c, 0xff, + 0x95, 0x99, 0xde, 0xd8, 0x75, 0x76, 0x18, 0x8a, 0x3f, 0x95, 0x2a, 0xcc, + 0xc5, 0x54, 0x03, 0x44, 0x3a, 0x71, 0x61, 0x6b, 0x2f, 0x49, 0x3f, 0xe5, + 0xe9, 0x3e, 0xc2, 0xa8, 0x79, 0x1a, 0x78, 0x1c, 0x34, 0x55, 0xca, 0x08, + 0x11, 0x59, 0x4c, 0x01, 0xc5, 0x3a, 0x49, 0x05, 0xd3, 0x95, 0x3b, 0x8d, + 0x1e, 0xc0, 0x94, 0x92, 0x64, 0x83, 0xf7, 0xa3, 0x48, 0xd3, 0xd8, 0xfa, + 0x6b, 0xe1, 0xd6, 0xfb, 0x26, 0x4c, 0xbe, 0xc8, 0xa9, 0x51, 0x50, 0xd3, + 0x95, 0xbd, 0x53, 0x46, 0xe8, 0xd4, 0x2d, 0xa0, 0x64, 0x9d, 0x51, 0xcc, + 0x9c, 0xa2, 0x79, 0x5f, 0x4c, 0xb8, 0xfe, 0x43, 0x1b, 0x26, 0x28, 0x6d, + 0x38, 0x3c, 0x7c, 0xb5, 0x0d, 0xaf, 0x38, 0xc6, 0x28, 0x3b, 0xeb, 0x9a, + 0x31, 0xc7, 0xfe, 0xbe, 0x04, 0x5f, 0xbf, 0x36, 0xd3, 0xd7, 0x38, 0x1e, + 0x8a, 0x48, 0xe1, 0x85, 0x46, 0x1d, 0xbf, 0x11, 0xe1, 0x28, 0xdc, 0xc4, + 0xaf, 0x4f, 0xab, 0x76, 0x02, 0x3c, 0x99, 0x56, 0x05, 0xb1, 0x5b, 0x87, + 0x9d, 0x18, 0x66, 0xac, 0x86, 0x27, 0x8c, 0xe8, 0x9b, 0x3d, 0x6c, 0x9c, + 0x5b, 0x8c, 0xfc, 0xfe, 0xd9, 0x91, 0xe7, 0xeb, 0x0c, 0x73, 0x97, 0xd5, + 0x51, 0xb7, 0x38, 0x52, 0xb8, 0x74, 0xd9, 0xd2, 0xb8, 0x52, 0x3e, 0xbc, + 0x99, 0x48, 0xe8, 0xd2, 0xd1, 0x86, 0x40, 0xb7, 0xce, 0x04, 0xb6, 0x4f, + 0xe8, 0x9b, 0xd2, 0x71, 0x92, 0x96, 0x91, 0xd6, 0xb5, 0x48, 0xeb, 0x2b, + 0xfb, 0xe8, 0x1a, 0x87, 0xb3, 0xc3, 0x9a, 0x39, 0xb4, 0x05, 0xa7, 0x86, + 0xe9, 0x5a, 0x1c, 0x88, 0xfd, 0x63, 0x14, 0x46, 0x9a, 0xf7, 0x13, 0x65, + 0xcf, 0x92, 0x6f, 0x83, 0x96, 0x9e, 0x6a, 0xe0, 0x54, 0x49, 0x57, 0x6f, + 0x69, 0xdf, 0xb1, 0x81, 0x71, 0xf6, 0xc9, 0xf9, 0xb7, 0xbe, 0x44, 0x6f, + 0x08, 0x90, 0x77, 0x84, 0xf4, 0x85, 0xee, 0xa0, 0x31, 0x64, 0x34, 0xab, + 0x7a, 0xf9, 0xd0, 0xa7, 0xdc, 0x0b, 0xed, 0x54, 0xf6, 0x16, 0x38, 0x73, + 0xe5, 0x27, 0x84, 0xaf, 0x4e, 0x51, 0x29, 0x9c, 0x2d, 0x53, 0xfe, 0x9d, + 0x21, 0xf3, 0xa8, 0x13, 0xa8, 0xc2, 0xe7, 0xb8, 0x0c, 0x1f, 0x09, 0x67, + 0xf8, 0x20, 0xcc, 0xf0, 0xf4, 0x06, 0xb1, 0x1b, 0xb1, 0x2f, 0x65, 0x49, + 0x25, 0xa6, 0x4d, 0xa1, 0x79, 0xe9, 0x08, 0xfd, 0xd9, 0xc8, 0x1f, 0xa2, + 0x6a, 0xe7, 0x39, 0xba, 0x2e, 0x78, 0xb4, 0xaf, 0xdf, 0x40, 0xad, 0x7b, + 0x7d, 0xf0, 0x6a, 0xe9, 0x27, 0x46, 0x69, 0xec, 0x4d, 0x7c, 0xde, 0xa2, + 0x67, 0x4f, 0x20, 0x7d, 0xfb, 0x6d, 0x29, 0xa8, 0xaf, 0x65, 0x86, 0xa0, + 0x80, 0xf1, 0xd8, 0x4a, 0xbd, 0x72, 0xe9, 0x6d, 0x35, 0x1b, 0xd2, 0x36, + 0x4c, 0x0d, 0x65, 0x32, 0xe5, 0xde, 0x26, 0xa1, 0x42, 0xae, 0x0a, 0xd9, + 0xd0, 0x7e, 0xba, 0xa1, 0x5b, 0x1b, 0x3b, 0x31, 0xc8, 0x8c, 0xe1, 0xa6, + 0x82, 0x53, 0x23, 0x6b, 0x91, 0xbf, 0xd8, 0x6b, 0x50, 0x36, 0x0c, 0x93, + 0x82, 0xd2, 0x5e, 0xc6, 0x39, 0x28, 0xe7, 0x23, 0x2f, 0xed, 0xc3, 0x11, + 0x9c, 0x53, 0x3d, 0x14, 0x77, 0xf4, 0x5d, 0x89, 0x82, 0xf3, 0x9f, 0xf2, + 0xc7, 0x51, 0xba, 0x46, 0x59, 0xe9, 0x5b, 0xe4, 0xf1, 0x8c, 0xf3, 0x43, + 0x99, 0x14, 0xfc, 0x29, 0xb4, 0x3d, 0x64, 0x87, 0x89, 0xcc, 0x18, 0xef, + 0x24, 0xc8, 0xaa, 0xba, 0x69, 0xed, 0x01, 0x2f, 0xc4, 0xe6, 0x0f, 0x67, + 0xf8, 0x8a, 0x3c, 0xe0, 0xec, 0x96, 0x96, 0xeb, 0xca, 0x00, 0x0d, 0x5b, + 0xcf, 0x60, 0xbc, 0x2f, 0xa1, 0xdc, 0xd2, 0xed, 0xfc, 0x40, 0x62, 0x9c, + 0x7f, 0x94, 0x0d, 0x58, 0xfa, 0x51, 0x69, 0x47, 0xe8, 0x28, 0xea, 0x7d, + 0x7a, 0x86, 0xce, 0x1d, 0x53, 0x7d, 0x31, 0xd9, 0x96, 0xdf, 0xe1, 0xf3, + 0xbd, 0x5b, 0xc0, 0x44, 0x71, 0xbe, 0x6a, 0x74, 0x4f, 0x4c, 0xbc, 0xa3, + 0x6c, 0x0e, 0x69, 0x82, 0x9d, 0xb9, 0x70, 0x21, 0xb4, 0x43, 0x50, 0x23, + 0x0e, 0x76, 0x20, 0xbf, 0xa5, 0xbd, 0x30, 0xd2, 0xe9, 0xbc, 0x6d, 0x42, + 0xf5, 0x54, 0x38, 0xd8, 0x4e, 0x6f, 0x7c, 0x2b, 0xf5, 0xd1, 0x7d, 0xed, + 0xf4, 0x37, 0x57, 0xb9, 0x17, 0x48, 0x3b, 0xd2, 0x86, 0x1a, 0x59, 0x58, + 0xc8, 0x93, 0x48, 0xe1, 0x87, 0xd1, 0xfa, 0x0d, 0x50, 0x94, 0x70, 0xfe, + 0x43, 0xfa, 0xb9, 0xf0, 0xa9, 0x94, 0xef, 0xab, 0xdb, 0x20, 0xde, 0x1d, + 0x11, 0xb4, 0xca, 0x3a, 0xd3, 0xbb, 0x50, 0xf2, 0x32, 0x72, 0xed, 0x06, + 0xe5, 0xb4, 0x90, 0xeb, 0x3f, 0x8b, 0xd2, 0xb0, 0xf9, 0x18, 0x76, 0x46, + 0xa6, 0x21, 0xa7, 0xa2, 0x63, 0x95, 0xd3, 0x44, 0xe8, 0x69, 0x29, 0x74, + 0xa7, 0x72, 0x22, 0x3e, 0x13, 0x6d, 0x80, 0x93, 0x72, 0x26, 0xbd, 0x69, + 0x03, 0x53, 0x49, 0x32, 0x4c, 0xfc, 0xb3, 0x34, 0x83, 0x9f, 0x04, 0x79, + 0x9e, 0x5c, 0xe1, 0xa8, 0xfc, 0x6c, 0x88, 0xde, 0x69, 0xf6, 0xbd, 0x7e, + 0x75, 0xde, 0x5b, 0x92, 0x1b, 0xca, 0x21, 0xe9, 0x7f, 0xbf, 0xff, 0x67, + 0xd1, 0xab, 0xf4, 0xc4, 0x65, 0xfc, 0xab, 0x4e, 0x42, 0xdb, 0xfa, 0x38, + 0x5d, 0x0b, 0x8a, 0xbc, 0x77, 0x3e, 0x5a, 0xd9, 0x7c, 0xc2, 0xd4, 0x79, + 0x58, 0xa1, 0x51, 0x5a, 0xdb, 0xe7, 0x89, 0xe4, 0x1d, 0x84, 0x8f, 0x1d, + 0x51, 0x35, 0x65, 0x41, 0xcd, 0x86, 0x54, 0x50, 0x95, 0xb2, 0x12, 0x5d, + 0xbd, 0xca, 0xb4, 0x50, 0x2a, 0x34, 0x6c, 0xd0, 0xda, 0x6f, 0xf7, 0x66, + 0x96, 0x31, 0x3b, 0x5b, 0x85, 0x2b, 0xdd, 0x76, 0xdf, 0x77, 0x42, 0x70, + 0x9d, 0x5a, 0x32, 0xc3, 0x8f, 0xca, 0xf4, 0x68, 0xc1, 0x7f, 0x24, 0x93, + 0xf1, 0x8f, 0x17, 0x3c, 0xe2, 0xcd, 0x43, 0x5e, 0x50, 0x12, 0xda, 0xea, + 0x6a, 0xe0, 0x88, 0xbf, 0x2a, 0x64, 0x2f, 0xfe, 0x9b, 0xac, 0x0b, 0xe9, + 0x39, 0x7f, 0x0e, 0xc7, 0x91, 0xa6, 0xbd, 0x39, 0xf4, 0x06, 0x64, 0x55, + 0x8b, 0x0a, 0xb9, 0x5d, 0x7f, 0x1f, 0x1d, 0xf3, 0x87, 0x36, 0x10, 0x27, + 0x91, 0x3f, 0xde, 0x70, 0x25, 0xf8, 0x38, 0x4f, 0x1c, 0x0f, 0x7b, 0x8d, + 0xb7, 0xee, 0xcd, 0x8d, 0x73, 0xd3, 0xd7, 0x1e, 0x0c, 0x35, 0x9a, 0x23, + 0x77, 0x56, 0xc0, 0x56, 0xb7, 0x39, 0xc0, 0x38, 0xb4, 0x65, 0x23, 0xf1, + 0xe3, 0x23, 0xbf, 0xc6, 0x5a, 0x7e, 0x8d, 0x1c, 0xbd, 0xaa, 0xdc, 0xc3, + 0xab, 0x5a, 0x9a, 0x91, 0x7f, 0x2d, 0xea, 0xff, 0x45, 0x94, 0xc2, 0x1f, + 0xeb, 0xc8, 0x2f, 0xca, 0x0a, 0x69, 0xd1, 0x6a, 0x7e, 0xec, 0x48, 0x9e, + 0x87, 0x4c, 0xa2, 0xd6, 0x64, 0x51, 0x6f, 0x70, 0x6e, 0xe6, 0x86, 0xe2, + 0x50, 0x93, 0x90, 0x8a, 0x1c, 0xf7, 0x71, 0x17, 0xa0, 0xeb, 0x8a, 0xec, + 0x77, 0x70, 0x60, 0xf2, 0x64, 0x09, 0xc5, 0x32, 0x94, 0xa8, 0x24, 0x62, + 0xcb, 0xea, 0x85, 0xa2, 0x2f, 0xa2, 0xf5, 0x21, 0x8d, 0xf3, 0x12, 0xea, + 0xb1, 0x76, 0xd4, 0xeb, 0x1f, 0x77, 0x7c, 0xcb, 0xfb, 0x82, 0x79, 0xeb, + 0x94, 0x52, 0xb4, 0x62, 0x7a, 0x24, 0x3a, 0x22, 0xb2, 0x90, 0x73, 0x3f, + 0x32, 0x44, 0x31, 0xe0, 0x70, 0x1e, 0x93, 0x5d, 0xa8, 0x27, 0xfe, 0x7e, + 0xf0, 0x71, 0xd4, 0x13, 0xef, 0xc1, 0x74, 0x1f, 0x6f, 0x4d, 0x8e, 0x99, + 0x95, 0x43, 0xdd, 0x51, 0x5b, 0xf1, 0x5b, 0x32, 0xb5, 0x67, 0x0c, 0xc5, + 0xaf, 0x23, 0xd5, 0xdf, 0x3e, 0x90, 0x02, 0x1b, 0x61, 0x2b, 0xfc, 0x36, + 0x71, 0xf5, 0x7f, 0x3a, 0x34, 0xc0, 0x4f, 0x00, 0x4a, 0xde, 0xc2, 0x9a, + 0x54, 0xe1, 0xc7, 0xf9, 0xf5, 0x5e, 0x9d, 0xfb, 0x53, 0xee, 0xc2, 0x86, + 0xbd, 0x1b, 0xe8, 0x8a, 0xf7, 0x67, 0x43, 0x5c, 0x8e, 0x07, 0x35, 0x30, + 0x8f, 0xed, 0x70, 0x65, 0x63, 0x3b, 0xb3, 0x13, 0x4a, 0x0c, 0x12, 0x38, + 0x98, 0x66, 0xe2, 0xd4, 0x9c, 0x5a, 0x91, 0xb3, 0xbb, 0x92, 0xf0, 0x64, + 0x6a, 0x49, 0x10, 0x63, 0xc2, 0xf5, 0x95, 0xaa, 0x08, 0x34, 0x51, 0x38, + 0x9e, 0x42, 0x5d, 0xa9, 0x14, 0x38, 0x6e, 0x4b, 0x3b, 0xd5, 0x2f, 0x1e, + 0x8d, 0xfe, 0x2a, 0x0a, 0x25, 0x29, 0x72, 0x52, 0x2e, 0x67, 0x79, 0x69, + 0x69, 0xdf, 0x8d, 0x3e, 0xee, 0x58, 0xe7, 0xad, 0x2a, 0x3f, 0xc8, 0x1d, + 0x8c, 0x32, 0xa8, 0x23, 0x3f, 0x16, 0xa5, 0xf5, 0xee, 0xdd, 0x70, 0x3e, + 0xf4, 0x6c, 0xe8, 0xe2, 0x86, 0x2a, 0x77, 0x01, 0xc3, 0x7a, 0x3f, 0xe6, + 0x6c, 0x39, 0x9e, 0x09, 0xb4, 0xe6, 0xc6, 0x76, 0x28, 0xd1, 0x4a, 0x64, + 0x82, 0xfa, 0x54, 0x4e, 0xe8, 0x71, 0x81, 0x91, 0xc9, 0x54, 0xe2, 0xc6, + 0x30, 0xa5, 0xae, 0xfa, 0xe1, 0xfb, 0xb0, 0x74, 0x90, 0x96, 0x2a, 0x25, + 0x9e, 0x0b, 0x99, 0x7d, 0x2f, 0x70, 0x0d, 0x6b, 0xe9, 0x2e, 0x5d, 0x17, + 0x24, 0x6d, 0x25, 0x90, 0xbd, 0xd1, 0x24, 0x36, 0x8e, 0x0f, 0xde, 0xae, + 0xa4, 0xbd, 0x55, 0x49, 0xab, 0x2e, 0x27, 0xfc, 0x41, 0x6e, 0xb9, 0x12, + 0x72, 0x8b, 0x12, 0xc2, 0x96, 0x7f, 0x89, 0xbe, 0x0f, 0x25, 0x0a, 0xd1, + 0x8d, 0x4a, 0xc8, 0xb3, 0x21, 0x0d, 0x96, 0x57, 0xb2, 0x96, 0xb6, 0xc3, + 0x1d, 0x4d, 0x96, 0x78, 0x9d, 0xd2, 0xb7, 0x57, 0x69, 0x77, 0x7d, 0x47, + 0xce, 0x1c, 0x94, 0x5a, 0xa1, 0xba, 0xd0, 0x56, 0x21, 0x4d, 0xda, 0x29, + 0x18, 0x91, 0x12, 0x7e, 0x3c, 0xd9, 0x16, 0xfa, 0x51, 0x79, 0x26, 0x86, + 0xe0, 0xa8, 0x29, 0xda, 0x29, 0xa4, 0xcb, 0xd8, 0xa3, 0x73, 0x30, 0xaf, + 0xad, 0x2e, 0xb4, 0x5d, 0x30, 0xc8, 0x19, 0x35, 0xa4, 0x08, 0x90, 0x86, + 0xed, 0x70, 0xba, 0x1d, 0x59, 0x04, 0x96, 0xe9, 0x82, 0x07, 0x3b, 0xf7, + 0x85, 0x48, 0xd1, 0x76, 0xa1, 0x5f, 0x2e, 0x02, 0x70, 0x54, 0x5d, 0x2f, + 0xb6, 0x67, 0x00, 0x84, 0xdd, 0xd8, 0xc2, 0xcf, 0x87, 0xca, 0xc1, 0x83, + 0x1c, 0xea, 0x59, 0xec, 0xef, 0x09, 0x7d, 0x1a, 0xf8, 0x50, 0xa9, 0x7f, + 0x6a, 0xe6, 0xd5, 0x73, 0x7f, 0x50, 0xfa, 0xc5, 0x7f, 0x3a, 0x42, 0x67, + 0x2f, 0x47, 0xe2, 0xbb, 0x47, 0xe8, 0x58, 0x51, 0x01, 0xb3, 0xc1, 0xd4, + 0x31, 0x6b, 0x83, 0xd6, 0xd6, 0x13, 0x62, 0x3d, 0x05, 0x8c, 0xa8, 0x75, + 0x78, 0xc5, 0x74, 0xc6, 0x99, 0x4a, 0x4f, 0x9b, 0x71, 0x66, 0x4a, 0xc4, + 0xa9, 0x95, 0x99, 0x69, 0x3e, 0x61, 0xd1, 0xcc, 0x14, 0xdf, 0x51, 0x6e, + 0xa7, 0xe0, 0x99, 0x49, 0x77, 0xac, 0x80, 0x8d, 0x29, 0x41, 0x5e, 0xe8, + 0x93, 0x94, 0x95, 0x76, 0x5f, 0x62, 0xbf, 0xa8, 0x24, 0x0f, 0x1f, 0xc6, + 0xd8, 0x7f, 0x44, 0x1b, 0xf9, 0x1e, 0x18, 0xbd, 0x9f, 0x77, 0x84, 0xde, + 0x1b, 0x0d, 0x05, 0x1b, 0x8b, 0x76, 0x09, 0x70, 0x3c, 0xd6, 0x39, 0x37, + 0xa4, 0x9e, 0xa8, 0x91, 0x7f, 0x12, 0xba, 0x09, 0x75, 0xf6, 0x55, 0x90, + 0xd0, 0xdf, 0x62, 0xfe, 0xf8, 0xce, 0xd4, 0xd0, 0x52, 0xf3, 0x73, 0xed, + 0xd5, 0xe6, 0x4f, 0xa3, 0xdb, 0x39, 0x15, 0x34, 0xb5, 0x23, 0x1e, 0x8e, + 0x47, 0xb6, 0x6d, 0x16, 0x98, 0x63, 0x8b, 0xb7, 0x35, 0x72, 0x8d, 0xed, + 0xc1, 0xd9, 0x9b, 0xb7, 0x9a, 0x3a, 0xb6, 0x0b, 0x6c, 0xf7, 0x0e, 0xcb, + 0xa3, 0xdb, 0xc4, 0xf6, 0xdd, 0x82, 0xea, 0x98, 0x77, 0xdb, 0x31, 0x6e, + 0x9b, 0x65, 0x47, 0xbb, 0x6a, 0x33, 0x6d, 0x89, 0xb2, 0x7e, 0x24, 0xf6, + 0x6a, 0x1f, 0xbd, 0x5d, 0xf1, 0x49, 0x5d, 0x36, 0xa8, 0x91, 0x8f, 0xa4, + 0x00, 0x99, 0x9e, 0x51, 0xd5, 0xdc, 0xbe, 0x59, 0x48, 0x93, 0x55, 0xbc, + 0x03, 0x5e, 0x81, 0x6d, 0x66, 0x8b, 0x27, 0x47, 0xd0, 0x20, 0x2f, 0x20, + 0xfb, 0xe9, 0x9e, 0xa5, 0xd4, 0x61, 0x22, 0x3a, 0xfd, 0xf1, 0x4e, 0x2e, + 0xf4, 0x68, 0xe5, 0x7d, 0x95, 0x0b, 0x43, 0xc0, 0x4c, 0xf5, 0x3e, 0x13, + 0x9a, 0xc1, 0x6a, 0xbd, 0xdd, 0x21, 0xd6, 0x0d, 0x9a, 0xa9, 0xde, 0x62, + 0xff, 0x99, 0xd1, 0xbb, 0xd9, 0x62, 0x1d, 0x69, 0xa8, 0xa8, 0x6c, 0x3b, + 0x92, 0x76, 0x48, 0x0d, 0xdc, 0xd6, 0xf4, 0x43, 0xd6, 0x90, 0xd1, 0x32, + 0x0e, 0xd8, 0xf0, 0x73, 0xed, 0x9b, 0x10, 0xce, 0x15, 0xdb, 0x2e, 0x5a, + 0x9e, 0x6b, 0x3f, 0xb4, 0xb5, 0x4d, 0x50, 0x1f, 0xa3, 0x1c, 0xff, 0x67, + 0x89, 0xe2, 0xed, 0x87, 0xb7, 0x22, 0xcd, 0x4d, 0xb0, 0x4b, 0x7c, 0xce, + 0x6b, 0x02, 0x9c, 0xaa, 0xc8, 0xd9, 0x8d, 0xf1, 0x5b, 0x84, 0x9c, 0x53, + 0x1f, 0x6d, 0xcd, 0xb7, 0x64, 0xc0, 0x05, 0xcb, 0x5b, 0xdc, 0x02, 0xef, + 0x3c, 0xaf, 0xd8, 0xfe, 0x7a, 0xfb, 0x06, 0x2f, 0x09, 0x3b, 0x03, 0xdb, + 0xda, 0xad, 0x9c, 0x0a, 0xed, 0x55, 0x66, 0x27, 0x71, 0x8e, 0x95, 0x5e, + 0x13, 0x0c, 0xdd, 0x2e, 0xa8, 0xf3, 0xaa, 0x5a, 0x47, 0xe2, 0xbf, 0x1e, + 0xb2, 0x29, 0xb7, 0xc4, 0x76, 0x59, 0x1a, 0xdb, 0xcf, 0x46, 0x99, 0x08, + 0x5d, 0x25, 0x37, 0x12, 0xff, 0xf9, 0x10, 0x23, 0x96, 0x04, 0x48, 0x24, + 0xc6, 0x7d, 0x1a, 0x7d, 0x4d, 0xd0, 0x74, 0xd3, 0xb4, 0xcd, 0x8a, 0x1c, + 0xfc, 0x5e, 0xe2, 0x72, 0x54, 0x35, 0x9e, 0x11, 0x5d, 0xf0, 0xaa, 0xd7, + 0x02, 0xaa, 0x56, 0x35, 0x6a, 0x31, 0xeb, 0x13, 0x8c, 0x58, 0xe1, 0x61, + 0xc3, 0xf8, 0x2b, 0x38, 0x25, 0x96, 0x67, 0x23, 0xa2, 0x85, 0x44, 0xf2, + 0x73, 0xc4, 0xf6, 0x30, 0xea, 0xbc, 0x2b, 0x2a, 0x9f, 0xd9, 0x4a, 0xc4, + 0xd7, 0xdb, 0x7b, 0xa8, 0xc5, 0x1b, 0x41, 0xbb, 0x95, 0xdf, 0x55, 0xa9, + 0x0d, 0xab, 0x44, 0x36, 0x52, 0x3f, 0xcb, 0x0c, 0xda, 0xfd, 0x23, 0xf1, + 0x87, 0x86, 0xb4, 0x07, 0x77, 0x55, 0xb2, 0xe2, 0xc4, 0x40, 0xfd, 0x2c, + 0x0e, 0x87, 0xc0, 0x74, 0x84, 0x60, 0xd5, 0x90, 0x56, 0xfc, 0xbb, 0xd9, + 0xed, 0xa7, 0x2b, 0x7c, 0x5f, 0x40, 0xa5, 0xbf, 0x2b, 0x5a, 0x12, 0xa0, + 0xf3, 0x59, 0xb4, 0x0f, 0xc6, 0x20, 0x55, 0x95, 0x63, 0x0f, 0xa4, 0xce, + 0x69, 0x6e, 0xdf, 0x27, 0x18, 0xb1, 0x07, 0x4a, 0xb1, 0x07, 0x1a, 0xb1, + 0x07, 0x72, 0x05, 0x56, 0x4a, 0x09, 0x90, 0x03, 0xb4, 0x07, 0xe6, 0x0c, + 0xc5, 0x3b, 0x8d, 0x81, 0xf1, 0x86, 0x9c, 0xe0, 0x77, 0x82, 0xe3, 0x8d, + 0x05, 0x69, 0xcf, 0x04, 0xcf, 0x04, 0x59, 0xf7, 0x85, 0x51, 0x9c, 0x07, + 0x3b, 0x72, 0xe0, 0xb8, 0x25, 0x0d, 0x7b, 0x33, 0x03, 0x44, 0x2c, 0x85, + 0x39, 0x26, 0x6c, 0x13, 0x2d, 0x62, 0xfb, 0xc1, 0xad, 0xf4, 0x8b, 0x0e, + 0xc5, 0xf3, 0x95, 0x91, 0x43, 0x5b, 0xb9, 0x3c, 0x83, 0x74, 0x70, 0xeb, + 0x3e, 0x41, 0x87, 0x98, 0x2d, 0x09, 0xdc, 0xe1, 0x75, 0x81, 0xde, 0x3c, + 0x12, 0xcf, 0x1f, 0xa2, 0x6b, 0x83, 0x9f, 0xc3, 0x5e, 0xf9, 0x67, 0x94, + 0xd2, 0x07, 0x72, 0x49, 0x7b, 0xb5, 0xa0, 0x89, 0xd1, 0x3d, 0x03, 0x54, + 0x17, 0x1c, 0x0b, 0xf9, 0x90, 0x0a, 0x8d, 0x0d, 0x74, 0xdd, 0xed, 0x85, + 0x6d, 0x8e, 0xed, 0x62, 0x7b, 0x09, 0x90, 0xa7, 0xa0, 0xd9, 0x86, 0x50, + 0xa3, 0x6d, 0x99, 0xb0, 0x6f, 0x57, 0x03, 0x03, 0xdb, 0xda, 0xa9, 0x5c, + 0x7c, 0x79, 0xc4, 0xb6, 0x79, 0x6f, 0x03, 0xbd, 0xf7, 0x8b, 0x4a, 0xd0, + 0xe4, 0x8c, 0xbd, 0xa7, 0x21, 0x15, 0x68, 0xff, 0xd3, 0x15, 0xce, 0x98, + 0xff, 0xbb, 0x76, 0x2c, 0x81, 0x09, 0x6f, 0x6b, 0x6f, 0x43, 0x3b, 0xf0, + 0x06, 0x99, 0x89, 0x30, 0x2d, 0xf3, 0x2d, 0xcd, 0x94, 0x92, 0x8f, 0xd5, + 0x6e, 0xa3, 0xae, 0x88, 0x25, 0x03, 0xad, 0xa0, 0xdf, 0x20, 0x25, 0x4c, + 0xcb, 0xf9, 0x49, 0x3b, 0xb3, 0xe7, 0x25, 0x61, 0xe2, 0xa9, 0xf3, 0x5b, + 0x5b, 0xad, 0x26, 0x18, 0xb4, 0x5c, 0x41, 0x4a, 0xf8, 0x96, 0x77, 0x5b, + 0xbb, 0xd8, 0x5e, 0x85, 0x94, 0xc0, 0x07, 0x1a, 0xdb, 0xf7, 0x98, 0x59, + 0x51, 0xd5, 0x44, 0x9c, 0xc5, 0xd2, 0x4f, 0x84, 0x9c, 0x6e, 0xba, 0x96, + 0xf4, 0xbb, 0xde, 0x91, 0x78, 0xc7, 0xe0, 0x74, 0x60, 0x5a, 0x29, 0x44, + 0x2b, 0x46, 0x7a, 0x37, 0xf9, 0x11, 0xa2, 0xcd, 0x23, 0x53, 0x15, 0xca, + 0x38, 0xbf, 0xf5, 0x19, 0xe1, 0xc4, 0xf1, 0x84, 0xe5, 0xbb, 0x5e, 0x66, + 0x67, 0x3e, 0xbc, 0xc0, 0xfd, 0x39, 0xfa, 0x95, 0xe5, 0x95, 0xf6, 0x3f, + 0x46, 0x4b, 0x40, 0x15, 0xa1, 0xb4, 0xd2, 0x32, 0xa8, 0x12, 0x49, 0xc4, + 0x16, 0xf8, 0x3b, 0xd7, 0x13, 0xfd, 0x09, 0xd2, 0x4a, 0xb2, 0xc4, 0xe6, + 0xf6, 0x44, 0xbc, 0x24, 0x71, 0x22, 0xaa, 0xe2, 0x55, 0x91, 0x12, 0x88, + 0x20, 0xe6, 0xd4, 0xcd, 0x89, 0xb8, 0x2d, 0x41, 0xfd, 0x16, 0x0f, 0xdb, + 0x8c, 0xbf, 0x42, 0xa9, 0xc4, 0x46, 0x88, 0x1b, 0x69, 0xa5, 0xd5, 0x82, + 0xb4, 0xb2, 0x43, 0xa1, 0x95, 0xc8, 0xd6, 0x70, 0xbb, 0x2a, 0xac, 0x8a, + 0x10, 0x51, 0x7b, 0x80, 0xf6, 0x07, 0xa5, 0x5e, 0x36, 0x42, 0xef, 0xc1, + 0x8d, 0x71, 0x23, 0xf1, 0xba, 0xc1, 0x24, 0xa5, 0x14, 0x05, 0x28, 0xed, + 0xb8, 0x10, 0x82, 0x91, 0xf8, 0x42, 0xac, 0x3f, 0xc6, 0x51, 0x3a, 0x79, + 0x1a, 0xe9, 0xa4, 0x04, 0xde, 0x8c, 0xda, 0x02, 0xf1, 0x68, 0xbc, 0x83, + 0x84, 0x75, 0x87, 0xf2, 0x43, 0x8d, 0x3c, 0x4b, 0xe7, 0x80, 0x8b, 0x60, + 0xa7, 0x95, 0x89, 0x08, 0x96, 0x6e, 0x4f, 0x03, 0xb5, 0x45, 0x28, 0xc6, + 0x1d, 0x09, 0x10, 0x9f, 0x6f, 0xe4, 0xfd, 0xab, 0x80, 0x88, 0x2f, 0xb4, + 0x5f, 0x68, 0x5c, 0x91, 0xb7, 0x4a, 0xb8, 0x8c, 0x2d, 0x6f, 0xdb, 0x54, + 0xb4, 0x79, 0xfc, 0xba, 0x7b, 0x37, 0x25, 0xe2, 0x64, 0x84, 0xa6, 0x1b, + 0x19, 0x26, 0xd7, 0x63, 0x3b, 0x3b, 0xdf, 0xd8, 0xc6, 0x6c, 0xdf, 0x81, + 0x10, 0xed, 0xfc, 0x9a, 0x56, 0x90, 0x73, 0xe4, 0xd0, 0x5b, 0x87, 0xb9, + 0x1c, 0xca, 0x47, 0x54, 0xd0, 0xb5, 0xcd, 0xba, 0xbd, 0xcb, 0x42, 0x39, + 0x16, 0x9d, 0xd9, 0x37, 0x75, 0xbc, 0xbd, 0x8d, 0x6c, 0xdf, 0xbc, 0xb5, + 0x1e, 0x53, 0xa2, 0xa4, 0x38, 0xe6, 0xd9, 0x66, 0x45, 0x97, 0x84, 0xe3, + 0x2c, 0xb9, 0x2e, 0x3e, 0x49, 0x21, 0x1f, 0x8c, 0x9c, 0xdf, 0xc6, 0x6f, + 0x2f, 0x41, 0x1a, 0x44, 0xcd, 0x1b, 0x71, 0xf6, 0xd2, 0x08, 0xa5, 0x8e, + 0xcd, 0xed, 0x49, 0xea, 0x78, 0x7e, 0x38, 0x49, 0x1d, 0xaf, 0x0d, 0x53, + 0x2b, 0x84, 0xee, 0x50, 0x49, 0xc4, 0xff, 0x3c, 0x72, 0x6d, 0xfe, 0xd7, + 0x47, 0xf3, 0x37, 0xb7, 0x8b, 0x4a, 0x8e, 0x30, 0xb5, 0x5b, 0x30, 0xbc, + 0x6d, 0xf8, 0xea, 0xca, 0x76, 0x4f, 0x43, 0x1a, 0x86, 0x1f, 0xc2, 0x74, + 0xf6, 0xed, 0x4f, 0xb4, 0x2f, 0x48, 0xb6, 0xe0, 0x54, 0x9d, 0xd2, 0x02, + 0x7a, 0x33, 0xb5, 0x45, 0xb6, 0x7d, 0x17, 0x75, 0x7a, 0xd4, 0xba, 0x82, + 0x9d, 0x34, 0x2c, 0x2c, 0x0c, 0x1e, 0x3b, 0xbf, 0xd5, 0x1e, 0x58, 0xe0, + 0x7d, 0x97, 0x2b, 0xc3, 0xfe, 0xdd, 0x3f, 0x40, 0x1c, 0xc9, 0xbd, 0x17, + 0xf7, 0x0c, 0x27, 0x29, 0xe3, 0x81, 0x61, 0x62, 0xfb, 0x30, 0xea, 0x84, + 0xbf, 0x53, 0xea, 0x2f, 0x45, 0x1d, 0x9c, 0xa7, 0xa7, 0xee, 0x30, 0xa8, + 0x20, 0x26, 0x57, 0xa8, 0x53, 0x1c, 0xaf, 0x57, 0x70, 0x17, 0x1c, 0x01, + 0xfe, 0xc2, 0x26, 0x7e, 0x73, 0xdb, 0x56, 0x7f, 0xc3, 0x12, 0x6c, 0xe3, + 0xe2, 0xbc, 0x25, 0xc2, 0xbe, 0x4d, 0xf5, 0x88, 0xdb, 0x05, 0xc3, 0x34, + 0x7e, 0x1e, 0x96, 0x74, 0xb5, 0x35, 0x34, 0xd7, 0x42, 0x25, 0xd7, 0x9d, + 0x23, 0xfe, 0x86, 0xc2, 0x75, 0xa8, 0xdb, 0x29, 0x69, 0x6e, 0x1e, 0xa6, + 0xa3, 0xed, 0x1f, 0x57, 0x4c, 0x8d, 0xeb, 0x5e, 0x51, 0x5d, 0xb3, 0xcb, + 0x36, 0x38, 0x7b, 0x02, 0x01, 0x29, 0xb9, 0x27, 0x89, 0xf1, 0x59, 0xfc, + 0x8d, 0xca, 0x4e, 0x62, 0x1a, 0xa6, 0x75, 0xbc, 0xa7, 0x7b, 0xeb, 0x2e, + 0x62, 0xcb, 0xf0, 0x6c, 0xf5, 0x70, 0x9e, 0xab, 0x5f, 0x5a, 0xfa, 0x94, + 0x2f, 0x38, 0xe3, 0xb0, 0x1d, 0xa7, 0x12, 0x76, 0xb4, 0xd6, 0x8b, 0x95, + 0xbd, 0xc2, 0x74, 0xf4, 0x52, 0x89, 0x3c, 0x1c, 0xff, 0x7c, 0x40, 0x6b, + 0x27, 0xfc, 0x79, 0x9d, 0xd1, 0xd3, 0xe6, 0x39, 0x70, 0x97, 0x0b, 0x52, + 0xbc, 0x87, 0xee, 0xa0, 0xf3, 0xeb, 0x7d, 0x38, 0xa6, 0xd5, 0xa8, 0x37, + 0xe5, 0x03, 0xd9, 0x99, 0x88, 0xbf, 0x9a, 0xd0, 0xc0, 0x6b, 0xa3, 0x7b, + 0xb3, 0x52, 0x7b, 0xed, 0x4a, 0x29, 0xbf, 0xc7, 0x52, 0x32, 0x65, 0xad, + 0x83, 0xf0, 0x0e, 0x4f, 0xd8, 0x73, 0x4e, 0xb7, 0xfc, 0xae, 0x2c, 0xef, + 0x8a, 0x3b, 0x28, 0xb7, 0x3c, 0x92, 0x80, 0x09, 0xda, 0xd3, 0x94, 0x36, + 0x59, 0x49, 0xd7, 0x32, 0x1c, 0xef, 0x1a, 0x20, 0x93, 0x3f, 0x88, 0xda, + 0x90, 0x9a, 0xfe, 0xfd, 0x1e, 0x4b, 0x45, 0xa7, 0x6c, 0x36, 0x44, 0xd4, + 0x90, 0x0e, 0x74, 0xd7, 0x95, 0xa7, 0xdb, 0x58, 0x60, 0x49, 0xb3, 0x32, + 0xa8, 0xdd, 0x84, 0x0d, 0x11, 0x94, 0xa2, 0xad, 0x04, 0xf3, 0x17, 0x0d, + 0xae, 0xf4, 0x16, 0xfb, 0x34, 0x68, 0x2d, 0xd6, 0x07, 0xb6, 0x08, 0x70, + 0xcc, 0xef, 0x77, 0xe6, 0xf7, 0xb4, 0x43, 0xb8, 0x8b, 0x87, 0x88, 0x48, + 0x78, 0x2f, 0x29, 0x2d, 0xea, 0x26, 0xd7, 0x15, 0xc8, 0x2a, 0x87, 0xc5, + 0xdf, 0x16, 0xa8, 0x10, 0x86, 0x24, 0x55, 0x84, 0x0f, 0xcc, 0x27, 0x8b, + 0x3d, 0x8d, 0xf6, 0x5e, 0xbe, 0x9a, 0x58, 0x3c, 0x20, 0xda, 0xbd, 0x06, + 0x3f, 0x71, 0xda, 0x4f, 0x35, 0xf2, 0x8d, 0x0e, 0x9a, 0x87, 0xde, 0x76, + 0x48, 0x5a, 0x80, 0x2f, 0xc7, 0x3a, 0x96, 0xf9, 0x87, 0xe3, 0x5f, 0x0c, + 0x98, 0x7c, 0x2f, 0xc0, 0xc2, 0xdb, 0x89, 0x8d, 0xea, 0x73, 0xf4, 0xab, + 0x9c, 0xc5, 0x6f, 0xf4, 0x1d, 0x04, 0x79, 0x21, 0x94, 0xfc, 0x55, 0x5a, + 0xd8, 0x80, 0x36, 0xde, 0x00, 0x71, 0x91, 0xa9, 0xc3, 0xb2, 0x14, 0x55, + 0x39, 0xf8, 0xc0, 0xc3, 0x9e, 0x2c, 0x4f, 0x8a, 0x9f, 0xf0, 0xaf, 0x7a, + 0xf6, 0x05, 0xb2, 0xb0, 0xc6, 0x63, 0x51, 0x68, 0x04, 0xcf, 0x8d, 0xd9, + 0x60, 0x5b, 0xdf, 0x61, 0xb4, 0x41, 0xec, 0x72, 0x1f, 0x3d, 0x1f, 0x0e, + 0x8a, 0x51, 0x57, 0xe3, 0x27, 0xd4, 0x4c, 0xa8, 0xa2, 0xb7, 0xe6, 0x6d, + 0x9d, 0x67, 0x70, 0x0e, 0xa0, 0x75, 0xb0, 0xa0, 0x6e, 0x7d, 0x67, 0xe9, + 0xdc, 0xfd, 0xf7, 0x41, 0xac, 0xa7, 0x8f, 0x38, 0x8a, 0xb1, 0x17, 0x57, + 0xac, 0x24, 0xce, 0x21, 0x84, 0xbf, 0x08, 0xdd, 0x87, 0x57, 0x90, 0x09, + 0x43, 0x32, 0x53, 0xa8, 0x2e, 0xb2, 0x03, 0x3c, 0xa1, 0xe1, 0x1d, 0x35, + 0x3c, 0xea, 0xf9, 0xc1, 0x3e, 0x3a, 0xdf, 0x69, 0xaf, 0x71, 0x54, 0xc1, + 0x93, 0x10, 0x6b, 0xe8, 0xb3, 0xfb, 0x4a, 0xc0, 0x3e, 0x17, 0xc2, 0xe0, + 0x60, 0x51, 0x43, 0x5f, 0x92, 0x70, 0x62, 0x2c, 0x50, 0x3b, 0xfa, 0x09, + 0x7a, 0x5e, 0x1c, 0x38, 0x4c, 0x73, 0x32, 0x80, 0x07, 0xd8, 0xa5, 0xb5, + 0xd1, 0xaf, 0x48, 0xe0, 0xe0, 0x91, 0xe3, 0xc3, 0x2e, 0x1d, 0xfa, 0x6e, + 0x41, 0x9f, 0xde, 0x47, 0x75, 0x1b, 0xbd, 0x8d, 0xa7, 0x77, 0xb6, 0xa3, + 0xdf, 0x49, 0x63, 0x9f, 0xd0, 0x60, 0xec, 0xf5, 0x89, 0x23, 0x74, 0xdd, + 0x20, 0xb6, 0x83, 0xae, 0xff, 0xb6, 0xfe, 0x12, 0xf5, 0x0d, 0xda, 0xae, + 0x23, 0xe0, 0x71, 0xe1, 0x03, 0xd7, 0x05, 0x16, 0x29, 0x6b, 0xc2, 0x1f, + 0xff, 0xc1, 0x6c, 0xe5, 0x4e, 0x4c, 0x4c, 0xe0, 0x59, 0xb4, 0x5e, 0x4b, + 0x7c, 0xc9, 0x3d, 0x18, 0x34, 0xdf, 0xbf, 0xdf, 0xff, 0xa9, 0x1a, 0xf5, + 0x27, 0xa9, 0x37, 0x19, 0x46, 0xc7, 0x0b, 0xb1, 0x0d, 0xc5, 0x6b, 0xfb, + 0x92, 0x37, 0x7f, 0x7e, 0x9a, 0xa0, 0x7b, 0x2a, 0xbe, 0xb9, 0xef, 0x73, + 0x38, 0xfe, 0xd1, 0xe8, 0x7d, 0x9f, 0xc3, 0xf1, 0x4b, 0xff, 0x7f, 0x78, + 0xdf, 0xe7, 0xff, 0xe9, 0x7d, 0x99, 0x41, 0xd4, 0xd3, 0xf4, 0x45, 0x5b, + 0x8f, 0x50, 0xed, 0x89, 0x7e, 0x57, 0x83, 0x5d, 0x23, 0xf1, 0x07, 0xfa, + 0xa8, 0x5b, 0xbd, 0x9f, 0x45, 0xf7, 0x9a, 0x3e, 0x1f, 0xbf, 0xbc, 0x32, + 0x50, 0x99, 0x15, 0x64, 0x0f, 0xa4, 0x3a, 0x34, 0xb1, 0xc1, 0xc1, 0x31, + 0x76, 0x9d, 0xa3, 0x18, 0x1a, 0x66, 0x8d, 0xc4, 0xef, 0xeb, 0xd3, 0x1d, + 0xa1, 0x7b, 0x23, 0x36, 0xf2, 0x2a, 0x1c, 0x27, 0x6f, 0xeb, 0xef, 0x86, + 0xf1, 0xb7, 0x5e, 0x67, 0xde, 0x48, 0xe2, 0xe6, 0x5f, 0x05, 0x89, 0x6d, + 0xaf, 0x37, 0x14, 0x44, 0x7b, 0x3b, 0xd8, 0x42, 0x7e, 0xbd, 0xe5, 0x37, + 0x0f, 0x3d, 0x5e, 0xf9, 0x01, 0xb8, 0x38, 0x32, 0xc1, 0x24, 0xe7, 0x57, + 0x6f, 0xe4, 0x7e, 0x58, 0x07, 0xe3, 0x8b, 0xcd, 0x1e, 0xe2, 0xe2, 0x1a, + 0x03, 0x5a, 0xff, 0xab, 0x82, 0x5e, 0x5e, 0x4a, 0xae, 0x37, 0xaf, 0xf7, + 0x9b, 0x7d, 0x57, 0xfc, 0xb1, 0x4e, 0x8e, 0xa6, 0xf0, 0x7f, 0x1a, 0x5d, + 0x98, 0x27, 0x92, 0x2e, 0xb8, 0x82, 0xb9, 0x72, 0xe4, 0xec, 0x6a, 0x0f, + 0xb7, 0xb0, 0xae, 0xb6, 0x72, 0x06, 0x3f, 0xa3, 0x6c, 0x5b, 0x7b, 0xab, + 0x97, 0x29, 0x05, 0xb9, 0x1a, 0x4c, 0x55, 0x13, 0xcd, 0xaa, 0xc0, 0x2a, + 0xb2, 0x08, 0x2d, 0xb6, 0xb4, 0xea, 0x07, 0xcd, 0x57, 0xfc, 0xcd, 0x1a, + 0x9f, 0xc7, 0xe2, 0xa5, 0xf7, 0x96, 0x5a, 0xbc, 0xeb, 0x03, 0x16, 0xff, + 0x5f, 0xa3, 0x7a, 0x9a, 0xd3, 0x7f, 0x0e, 0x69, 0x26, 0x80, 0x7d, 0xdf, + 0x08, 0xa6, 0x79, 0x40, 0x4c, 0xf3, 0x1e, 0xc5, 0xb7, 0x0e, 0x9f, 0x80, + 0xb2, 0xee, 0xd1, 0x34, 0xcf, 0x48, 0xc3, 0x79, 0x33, 0xea, 0xca, 0xfa, + 0xaa, 0xd3, 0x74, 0x1d, 0xa1, 0x7b, 0xa7, 0x5f, 0xf6, 0xa7, 0x3b, 0xe3, + 0x72, 0xcc, 0x41, 0x77, 0x1f, 0xb2, 0x55, 0xc3, 0xf1, 0xbf, 0x27, 0xe8, + 0xd9, 0x0b, 0x16, 0x7f, 0xf2, 0x1c, 0x4c, 0xd3, 0xbc, 0xfd, 0x58, 0x1e, + 0xcd, 0xdf, 0x88, 0xe5, 0x79, 0x7d, 0xb1, 0x8e, 0xbc, 0x40, 0x63, 0xc1, + 0x14, 0x58, 0xca, 0x3c, 0x76, 0xa4, 0xd0, 0x53, 0x84, 0xb6, 0x1b, 0x71, + 0xcc, 0xf0, 0x81, 0xed, 0x34, 0x6a, 0x37, 0xa7, 0x1f, 0xba, 0xa9, 0x7a, + 0x24, 0xfe, 0x44, 0x7f, 0xa3, 0xa3, 0x10, 0x6e, 0xf4, 0x35, 0x33, 0x96, + 0x7b, 0x4d, 0x7c, 0x1e, 0xda, 0x01, 0xb9, 0xde, 0x69, 0x3e, 0x32, 0x5e, + 0x5c, 0xa5, 0x0a, 0x53, 0x5b, 0x55, 0xa5, 0x9c, 0xd9, 0xc6, 0x88, 0x36, + 0xe7, 0x64, 0xb9, 0x91, 0x5f, 0x42, 0xf2, 0xd0, 0x5a, 0x80, 0x82, 0x5c, + 0xaf, 0xcb, 0x97, 0xe3, 0xa7, 0x3c, 0x8b, 0x9e, 0xfc, 0x48, 0xbf, 0x30, + 0xdf, 0x85, 0xe5, 0x94, 0xfa, 0x32, 0x55, 0x96, 0x7b, 0x51, 0xe7, 0xc6, + 0x54, 0x3a, 0xac, 0x89, 0xc5, 0xa8, 0x5c, 0xd4, 0x17, 0x6e, 0xea, 0x37, + 0x39, 0x78, 0x1f, 0x8d, 0xb1, 0x32, 0x79, 0x82, 0x5e, 0x52, 0xee, 0xfd, + 0x56, 0x62, 0x5c, 0x98, 0x2b, 0x97, 0xd2, 0xc4, 0xbd, 0x1d, 0xc2, 0x04, + 0xa9, 0x04, 0x72, 0xaa, 0xd6, 0x7a, 0x86, 0xe3, 0xde, 0x3e, 0x95, 0x98, + 0x8f, 0xd6, 0xff, 0x58, 0x1f, 0x13, 0x79, 0xe6, 0x5e, 0x46, 0xbc, 0x4b, + 0x47, 0xf8, 0xa5, 0x10, 0xf6, 0x5e, 0xe4, 0x4c, 0xbe, 0xa5, 0xe4, 0x22, + 0x47, 0xe7, 0x79, 0xde, 0xe8, 0xa7, 0x5c, 0x82, 0xf0, 0xfb, 0xb6, 0x3f, + 0x1b, 0xc2, 0xf1, 0xcc, 0x73, 0x08, 0x83, 0xd0, 0x4f, 0x63, 0x84, 0x7e, + 0x95, 0xf8, 0xaa, 0x57, 0x85, 0x1a, 0xe6, 0x46, 0xa0, 0xa7, 0x6c, 0x30, + 0xe1, 0xdd, 0xd1, 0xe4, 0x9d, 0x85, 0x2d, 0x90, 0x31, 0x8f, 0xe2, 0x9b, + 0xe2, 0x09, 0x5c, 0x19, 0xf3, 0x00, 0xfd, 0x27, 0xe8, 0xfa, 0xfd, 0x0e, + 0xba, 0xa3, 0x63, 0x10, 0xb5, 0x38, 0xb4, 0x26, 0xd0, 0x9e, 0xcf, 0x00, + 0x7a, 0x1b, 0xe7, 0x0f, 0x94, 0xb9, 0xd4, 0xad, 0xb4, 0x7f, 0x50, 0x66, + 0xcc, 0x67, 0x4e, 0x2f, 0x55, 0xf8, 0xaf, 0x2d, 0x63, 0x9e, 0xb2, 0x56, + 0x20, 0xf6, 0x61, 0x9f, 0x91, 0xf7, 0x14, 0x65, 0xcc, 0x51, 0xdb, 0xda, + 0xee, 0xcb, 0xa8, 0x1e, 0x8c, 0x7f, 0x32, 0x52, 0x8e, 0x7d, 0x92, 0x8e, + 0x7d, 0x42, 0xf7, 0x3b, 0x97, 0xa1, 0x84, 0x43, 0x59, 0x3c, 0x52, 0x86, + 0xfc, 0xa5, 0xd1, 0x96, 0xbc, 0xa7, 0xd5, 0x9c, 0x20, 0x3c, 0xbf, 0x94, + 0x9e, 0xc5, 0x75, 0x61, 0xa9, 0xc6, 0xd7, 0x34, 0xb9, 0x18, 0x78, 0x3f, + 0xd5, 0xdb, 0x82, 0x4a, 0xdf, 0x65, 0xcc, 0x9b, 0xf6, 0x04, 0x98, 0x28, + 0x7c, 0x26, 0x89, 0x40, 0x4a, 0x68, 0x89, 0x46, 0x2d, 0xfb, 0x42, 0x6a, + 0x27, 0x23, 0x6f, 0x0f, 0x11, 0xe4, 0x70, 0x74, 0xa5, 0x48, 0xc6, 0x3c, + 0x2d, 0x8f, 0x14, 0xd2, 0xf1, 0x87, 0x90, 0x71, 0x43, 0xf5, 0x86, 0x66, + 0xad, 0xd9, 0xa3, 0x67, 0x1a, 0x43, 0xcd, 0xe9, 0x76, 0x2f, 0x3d, 0xcb, + 0x8d, 0xca, 0x47, 0xba, 0x9e, 0xe3, 0x92, 0x62, 0x55, 0x6d, 0xb4, 0xd1, + 0xa3, 0x20, 0x3d, 0x70, 0x51, 0x8f, 0x5c, 0xca, 0x8c, 0xfa, 0xb7, 0xcf, + 0x43, 0xe8, 0x2c, 0x9e, 0xa5, 0x9f, 0xa6, 0xa3, 0xf5, 0x6c, 0x74, 0xd0, + 0xb2, 0x4c, 0x9e, 0x3f, 0xea, 0x33, 0x04, 0x95, 0xac, 0xad, 0xfe, 0xde, + 0xf4, 0x4c, 0xeb, 0xf6, 0x65, 0x8d, 0x0e, 0x0f, 0xa8, 0x7d, 0x80, 0x23, + 0x01, 0xec, 0x5d, 0x5c, 0x26, 0x81, 0xd8, 0x33, 0x7d, 0xd4, 0xca, 0x4a, + 0xe2, 0xee, 0x6a, 0x9e, 0x0c, 0x81, 0xda, 0xd3, 0x47, 0xf5, 0x1e, 0xf0, + 0x70, 0xaa, 0x6a, 0x0f, 0xd1, 0x71, 0x6f, 0x06, 0x99, 0x6a, 0x88, 0x6d, + 0xeb, 0x4b, 0x96, 0x9d, 0x88, 0x27, 0x12, 0x7d, 0x1d, 0x9b, 0x77, 0x78, + 0xb7, 0xb3, 0x28, 0xa5, 0xc6, 0x2a, 0xba, 0x4f, 0x5e, 0xce, 0xb9, 0xd0, + 0x2b, 0xed, 0xa9, 0x20, 0x5a, 0xeb, 0x37, 0xaf, 0xc8, 0x7b, 0x7a, 0x26, + 0x41, 0xa9, 0xe2, 0xf3, 0x1c, 0x83, 0x0b, 0xc1, 0xfa, 0x50, 0xb9, 0x77, + 0x95, 0x6a, 0x8c, 0x57, 0xf9, 0x92, 0x1c, 0xf8, 0x15, 0x29, 0x47, 0x2b, + 0xfc, 0x59, 0x94, 0x1e, 0x8d, 0x23, 0x6d, 0x0d, 0x7b, 0xcc, 0x94, 0x6e, + 0x7e, 0x5a, 0x9b, 0xeb, 0xad, 0xdf, 0x4e, 0xd7, 0x86, 0x53, 0xfa, 0xca, + 0xf5, 0xc2, 0x75, 0x20, 0x4d, 0x64, 0xe9, 0xf7, 0xe5, 0x2d, 0x01, 0xaa, + 0x13, 0xe4, 0x06, 0xa8, 0x3d, 0x3c, 0xd1, 0x58, 0x1f, 0x7a, 0x41, 0xfd, + 0x42, 0x2a, 0xdd, 0xdb, 0xdd, 0xb6, 0xfd, 0x63, 0xae, 0x6d, 0x73, 0xdb, + 0x8e, 0x43, 0x74, 0x67, 0x31, 0x5f, 0xbf, 0x99, 0xea, 0x38, 0x17, 0x02, + 0xdb, 0x70, 0x5c, 0x96, 0xa2, 0xd6, 0x33, 0x1c, 0x9f, 0x3f, 0x32, 0x9a, + 0xa2, 0x61, 0x89, 0x99, 0x9e, 0x10, 0x47, 0xef, 0xb0, 0x4c, 0xad, 0x59, + 0xc2, 0x06, 0x3b, 0xb2, 0xfc, 0xc6, 0x1a, 0x63, 0x75, 0x96, 0x3f, 0x07, + 0xb6, 0x07, 0x76, 0x21, 0xff, 0x33, 0xcc, 0xa5, 0xb2, 0x7b, 0xb7, 0x63, + 0x38, 0x5e, 0x3e, 0xd2, 0x88, 0xf4, 0x3e, 0x9f, 0x68, 0xb1, 0x97, 0x27, + 0x8c, 0xe8, 0xf9, 0x15, 0xf7, 0x29, 0x7d, 0xd7, 0x9b, 0xe4, 0x77, 0x0a, + 0xdf, 0x03, 0x4a, 0x57, 0x74, 0xdc, 0xaa, 0xee, 0xf7, 0x6e, 0xde, 0xb2, + 0x79, 0x4b, 0x2d, 0xd5, 0xee, 0xb6, 0xd0, 0x9d, 0x2a, 0x52, 0x4e, 0xc0, + 0xee, 0x81, 0x52, 0x8b, 0xd4, 0x58, 0x70, 0x11, 0x32, 0xbc, 0x0e, 0x61, + 0x8c, 0x64, 0x09, 0x38, 0x70, 0x3c, 0x6c, 0x74, 0x6c, 0x0a, 0xe9, 0xab, + 0xde, 0xd3, 0x67, 0x78, 0xf4, 0xc8, 0x2f, 0x23, 0x0b, 0x87, 0xe2, 0x6f, + 0x8e, 0x68, 0x6b, 0x0c, 0x1e, 0x8b, 0xff, 0xea, 0x6a, 0x6e, 0xfa, 0xbf, + 0x25, 0x60, 0xc6, 0x51, 0xfe, 0x21, 0xd2, 0xeb, 0x2e, 0x35, 0xe2, 0x77, + 0x30, 0x91, 0xf0, 0x62, 0xcb, 0xc1, 0xde, 0x58, 0x98, 0x17, 0xa0, 0x73, + 0xca, 0x55, 0x89, 0x2c, 0xdf, 0x2a, 0x62, 0x59, 0xa9, 0xf6, 0x02, 0xdf, + 0xac, 0x55, 0x9d, 0x40, 0xbb, 0xdc, 0x7d, 0x4c, 0x2f, 0x5a, 0xea, 0xb6, + 0x43, 0x69, 0x96, 0x04, 0xce, 0x8c, 0xd1, 0xdd, 0x8a, 0x93, 0x13, 0x06, + 0x9f, 0xda, 0x9b, 0xe7, 0xd9, 0xcb, 0xf7, 0xa8, 0xeb, 0x02, 0x6e, 0x6f, + 0x96, 0x1f, 0xec, 0xa5, 0x8a, 0x3c, 0x39, 0x84, 0x94, 0xc8, 0xfa, 0xf2, + 0x3c, 0x94, 0x42, 0xff, 0x19, 0x4d, 0xd2, 0x64, 0x22, 0x91, 0xf8, 0x00, + 0x9f, 0x17, 0xe9, 0xb7, 0x8e, 0x2d, 0x9b, 0x89, 0x5b, 0xd8, 0xac, 0xba, + 0x7f, 0x53, 0x2d, 0x5d, 0x07, 0x4d, 0x75, 0x31, 0xf5, 0x23, 0x2c, 0x00, + 0xda, 0xd1, 0x1b, 0xf9, 0x4d, 0xa1, 0xf4, 0x9a, 0xf4, 0x2a, 0xb3, 0x67, + 0x28, 0xbe, 0x74, 0x04, 0x5b, 0x6b, 0xb7, 0x06, 0x12, 0xf1, 0xf2, 0x44, + 0x7d, 0xc0, 0x1a, 0x58, 0x02, 0x9a, 0x93, 0x6d, 0x3b, 0xb6, 0x20, 0x85, + 0x25, 0xeb, 0x1f, 0x9f, 0xa0, 0xfd, 0xa8, 0x52, 0x76, 0xfd, 0xee, 0x49, + 0xd0, 0xd9, 0x40, 0x8a, 0x43, 0xda, 0x26, 0x2d, 0xa1, 0x63, 0x11, 0x62, + 0xaa, 0x3e, 0xfa, 0x0b, 0x7d, 0x1a, 0x1b, 0x8e, 0xcc, 0x98, 0x75, 0x88, + 0xca, 0x3c, 0xf5, 0x08, 0x5d, 0x35, 0xc0, 0xc2, 0x40, 0x7c, 0x6a, 0x82, + 0xee, 0x43, 0x85, 0x18, 0xe9, 0x0b, 0xa2, 0xf4, 0x83, 0xc2, 0x34, 0x30, + 0x1a, 0xb3, 0x8c, 0x87, 0x85, 0x72, 0xf9, 0x90, 0x60, 0x97, 0x5f, 0x69, + 0xdf, 0xd9, 0xbe, 0xd6, 0x0b, 0xb1, 0x17, 0xfa, 0xd9, 0xbc, 0x72, 0x49, + 0x05, 0xba, 0x8a, 0xc5, 0x01, 0x15, 0x1f, 0xf1, 0xb2, 0xd3, 0x0b, 0x4a, + 0xcb, 0xba, 0x55, 0x90, 0x55, 0x6a, 0x38, 0xa5, 0xf6, 0xdf, 0xe2, 0xd7, + 0xb9, 0xad, 0xa5, 0xea, 0x53, 0x8f, 0xf9, 0xdf, 0xf1, 0x17, 0x94, 0xda, + 0x30, 0x9d, 0xc9, 0x4d, 0x77, 0xab, 0x2f, 0xf6, 0x47, 0xfc, 0xe3, 0x7a, + 0x73, 0x72, 0x7e, 0xd1, 0xfe, 0x4a, 0x7b, 0x73, 0xfb, 0x3a, 0x6f, 0x5b, + 0xbb, 0xcf, 0x9b, 0x61, 0x5c, 0xc2, 0x99, 0x8d, 0x5a, 0xd9, 0xcc, 0x36, + 0xb7, 0x67, 0x78, 0xe5, 0x28, 0x3d, 0xfb, 0x73, 0x67, 0xfb, 0x67, 0x51, + 0x88, 0xa5, 0x21, 0x07, 0x80, 0x02, 0x95, 0x9f, 0xce, 0x91, 0xaa, 0x40, + 0x5d, 0xcb, 0xb9, 0x6f, 0xa9, 0xed, 0x89, 0x82, 0x7d, 0x38, 0x9e, 0x37, + 0xfc, 0x05, 0xea, 0xbb, 0x03, 0xf1, 0xf3, 0xca, 0xbc, 0x06, 0xc5, 0x1d, + 0x0b, 0xf4, 0x54, 0xce, 0x2d, 0xfe, 0x4d, 0x9b, 0xb6, 0x2c, 0x33, 0xc3, + 0x9b, 0x9b, 0x54, 0xb5, 0xde, 0xda, 0x2d, 0xb5, 0x3a, 0x87, 0xdf, 0x35, + 0x1c, 0xd7, 0x0e, 0xab, 0x7d, 0x05, 0x75, 0xf5, 0x75, 0xac, 0xaf, 0x0d, + 0x9f, 0x0b, 0xf8, 0xf0, 0xf5, 0x94, 0xf7, 0xe4, 0xbe, 0x04, 0xa6, 0x6a, + 0x7c, 0x36, 0xe1, 0xf3, 0xc2, 0x4b, 0xca, 0xde, 0x38, 0x1c, 0x61, 0xe9, + 0x0a, 0x5f, 0x5a, 0x25, 0x83, 0x69, 0xcb, 0x6a, 0x53, 0x47, 0x8f, 0x56, + 0x7d, 0x62, 0xcb, 0x36, 0x51, 0xcd, 0x9c, 0x58, 0xe8, 0x52, 0xc7, 0x3a, + 0x12, 0xf4, 0xdb, 0xc6, 0xff, 0x0c, 0x7f, 0x41, 0x09, 0x0f, 0x76, 0x04, + 0x0b, 0x6b, 0xf2, 0xee, 0xf4, 0xa6, 0xd1, 0xdd, 0xed, 0x65, 0x10, 0xb3, + 0x22, 0x8e, 0x74, 0x12, 0xed, 0x7d, 0xe2, 0xaf, 0xf4, 0x9b, 0x5c, 0x7b, + 0xfd, 0xc1, 0x72, 0xd4, 0x3b, 0x87, 0x6c, 0x8a, 0xfd, 0xc0, 0x28, 0x6b, + 0x69, 0xde, 0xc1, 0x7e, 0x6e, 0x51, 0xfa, 0x85, 0xa9, 0x52, 0xc7, 0x1e, + 0x53, 0xf6, 0xe5, 0xcd, 0x33, 0x2a, 0x6b, 0xd1, 0xd0, 0xbf, 0xe9, 0xdf, + 0xfc, 0x0f, 0x28, 0xfe, 0x85, 0x5f, 0xfb, 0xd7, 0x7e, 0xed, 0xcf, 0x52, + 0xbe, 0x7b, 0x7c, 0x92, 0x68, 0x6b, 0xa0, 0xf2, 0x84, 0xde, 0x67, 0x9e, + 0xd5, 0x39, 0xa6, 0x66, 0x5f, 0x9d, 0x03, 0xba, 0xcb, 0x93, 0xe7, 0xa1, + 0x64, 0xf9, 0xac, 0x01, 0x12, 0x6e, 0x13, 0x88, 0x4c, 0xf8, 0xb6, 0x5a, + 0xca, 0xc9, 0xf3, 0xfb, 0xfc, 0x7e, 0xfa, 0xb6, 0xf6, 0xed, 0x55, 0xde, + 0xe3, 0xfa, 0x50, 0x6f, 0xb3, 0xf7, 0xfa, 0xfd, 0x08, 0xd7, 0x9d, 0x28, + 0x79, 0xf4, 0xf6, 0xbd, 0xe8, 0x9a, 0x97, 0x60, 0x1c, 0x99, 0xf6, 0x5e, + 0x74, 0xf9, 0x12, 0x34, 0xa7, 0x44, 0x4f, 0x38, 0x30, 0x51, 0x98, 0xfb, + 0x3a, 0xb4, 0x58, 0xe7, 0xbe, 0x44, 0xbe, 0x2f, 0x2f, 0xf0, 0x12, 0xad, + 0x57, 0xa6, 0x7a, 0xf6, 0x6f, 0x12, 0xdd, 0xd7, 0xbf, 0x1c, 0x58, 0x1f, + 0x20, 0x15, 0xec, 0x49, 0x37, 0x5a, 0x08, 0x0e, 0xe9, 0xfa, 0xc0, 0x57, + 0x51, 0xa3, 0xe3, 0xf9, 0x7b, 0x60, 0x22, 0xda, 0x37, 0x30, 0xc6, 0xb7, + 0xd0, 0x75, 0xc1, 0xff, 0xfc, 0x32, 0x75, 0x4c, 0x9f, 0x48, 0xc4, 0x77, + 0x24, 0xe8, 0xe9, 0xac, 0x25, 0x50, 0xe8, 0x7f, 0xde, 0x7f, 0xef, 0xe8, + 0x49, 0x86, 0xb4, 0xcf, 0x26, 0x0e, 0xdd, 0x5b, 0xff, 0x7c, 0xfd, 0xf3, + 0x4b, 0x2f, 0x2d, 0xa5, 0xbd, 0x1f, 0x9c, 0xfc, 0xd7, 0x28, 0x6b, 0xa7, + 0x73, 0x75, 0x73, 0x13, 0x6c, 0x9e, 0xcb, 0x7f, 0x52, 0xa6, 0x67, 0x16, + 0x1b, 0xf9, 0x0a, 0xff, 0x3f, 0x70, 0x1c, 0x51, 0x58, 0x08, 0x24, 0x12, + 0x94, 0x37, 0x2f, 0x49, 0x0c, 0xc4, 0xff, 0x3a, 0x4c, 0xfb, 0xd1, 0xa4, + 0x9c, 0x2f, 0x6d, 0x16, 0x69, 0xbf, 0x0e, 0xc4, 0xff, 0x34, 0xac, 0xc2, + 0x30, 0x0d, 0xea, 0xbf, 0xf3, 0x15, 0x9c, 0x95, 0x89, 0xf4, 0x4c, 0x80, + 0x6e, 0x17, 0x8e, 0xaf, 0x22, 0xb2, 0xf3, 0xf9, 0xc0, 0x7d, 0x01, 0x32, + 0x83, 0x3d, 0x59, 0x10, 0x80, 0x09, 0x7d, 0x32, 0xb5, 0x30, 0x0f, 0x6d, + 0x23, 0x4e, 0xed, 0xa9, 0x34, 0xc7, 0xa1, 0x7b, 0x88, 0x5b, 0x25, 0x15, + 0x03, 0xbd, 0x33, 0x57, 0xe3, 0x0d, 0x4e, 0xf9, 0x38, 0x4a, 0x67, 0x15, + 0x34, 0x74, 0x97, 0xed, 0xce, 0xee, 0xc9, 0xf5, 0x81, 0xe7, 0x03, 0x28, + 0x1d, 0x45, 0x52, 0x01, 0xe1, 0x64, 0xee, 0x2f, 0xe5, 0xa9, 0xa3, 0xb9, + 0x75, 0xa3, 0xb9, 0x59, 0x89, 0x5a, 0xe1, 0x34, 0xbf, 0x16, 0xf3, 0x7f, + 0x18, 0xa5, 0xb4, 0x3a, 0x10, 0x7f, 0x6c, 0x98, 0x8e, 0x31, 0x43, 0x5f, + 0xd2, 0x4a, 0x1b, 0x88, 0x7f, 0x0f, 0xfd, 0xaa, 0xd8, 0x61, 0xe5, 0x0c, + 0xdd, 0x14, 0x88, 0x75, 0xa4, 0xb8, 0x1f, 0x3b, 0x42, 0x9a, 0xc6, 0x3a, + 0xf5, 0xa7, 0xb4, 0x8e, 0xb0, 0x17, 0xc2, 0xda, 0x93, 0x46, 0x9e, 0x44, + 0x90, 0x97, 0x28, 0x96, 0x80, 0x89, 0xa7, 0xb5, 0xb6, 0x0a, 0x5f, 0x74, + 0xa3, 0xb5, 0x10, 0x8b, 0xf7, 0x0f, 0xf1, 0xd0, 0xda, 0x59, 0xb3, 0x04, + 0x5a, 0x05, 0xf3, 0xb1, 0xf7, 0x75, 0xba, 0xb2, 0xdb, 0x39, 0x1d, 0xcc, + 0x09, 0xe8, 0xa6, 0x3e, 0x8a, 0x5c, 0xe1, 0x8f, 0x01, 0xe6, 0x86, 0x67, + 0x85, 0x42, 0x49, 0xc5, 0xd7, 0x05, 0x9e, 0x0d, 0xd0, 0x53, 0x8c, 0xce, + 0x07, 0xfe, 0xe0, 0xdf, 0xe9, 0x27, 0x8e, 0x0b, 0xdc, 0xa2, 0x80, 0xc1, + 0xbb, 0xd8, 0xff, 0xad, 0x5e, 0x10, 0x17, 0x19, 0x66, 0xf0, 0xf4, 0x5c, + 0x27, 0xb6, 0xa4, 0xa4, 0x1b, 0x44, 0x51, 0x3f, 0xd5, 0xad, 0x1a, 0xdf, + 0x0d, 0x8d, 0xdc, 0xdb, 0x81, 0x47, 0x05, 0x8d, 0x54, 0x1b, 0x80, 0xa7, + 0x7f, 0xed, 0xbd, 0xd5, 0x9a, 0x3e, 0x69, 0xca, 0x59, 0x52, 0xf1, 0x9d, + 0x9c, 0xec, 0x86, 0x7d, 0xd5, 0x8f, 0x0b, 0x4b, 0xb0, 0x4c, 0x7f, 0xa0, + 0xc5, 0xab, 0x02, 0x68, 0xc9, 0xb5, 0xa4, 0x4f, 0x9c, 0x7e, 0x96, 0x14, + 0xc1, 0x33, 0x36, 0xee, 0x06, 0xef, 0x24, 0xef, 0x7d, 0xfe, 0x79, 0xb5, + 0xa6, 0xda, 0x37, 0xfc, 0x9b, 0x90, 0xf2, 0x2f, 0xcd, 0x2b, 0xec, 0xcd, + 0x2e, 0x61, 0xba, 0x53, 0x60, 0x89, 0xfb, 0x78, 0xf4, 0x8e, 0x12, 0x15, + 0xd6, 0x60, 0x4d, 0x59, 0xed, 0xfe, 0x53, 0xf4, 0x20, 0x4f, 0x61, 0xa6, + 0xfe, 0x9e, 0x94, 0x87, 0xdc, 0xef, 0x44, 0x7f, 0x5c, 0xf5, 0x7d, 0x7e, + 0x93, 0xf0, 0x06, 0x85, 0xc0, 0xf8, 0x88, 0xbb, 0x33, 0x7a, 0x29, 0x00, + 0x93, 0x52, 0x7b, 0xda, 0x02, 0xb5, 0xdc, 0x59, 0xff, 0x21, 0xb4, 0x6b, + 0x6a, 0x02, 0x59, 0x5e, 0x1f, 0xb5, 0x90, 0x62, 0x8f, 0xa1, 0x2e, 0xa2, + 0x73, 0x85, 0xa2, 0x13, 0xe0, 0xe7, 0xd1, 0xdb, 0x6b, 0x33, 0x6a, 0x61, + 0xe2, 0x93, 0xa7, 0x6f, 0x0f, 0x3c, 0x5e, 0xd9, 0x68, 0xdf, 0x06, 0x3b, + 0x04, 0x38, 0xbe, 0xb9, 0x77, 0xa1, 0xfe, 0x94, 0x8e, 0xee, 0xdc, 0xf7, + 0x57, 0x1e, 0x45, 0x1d, 0x79, 0x81, 0x7f, 0x3b, 0x17, 0x0e, 0x9c, 0xf7, + 0xb7, 0xf9, 0x77, 0xf9, 0xcf, 0x60, 0xdb, 0xd7, 0x56, 0xbf, 0x6a, 0xaa, + 0x0a, 0x44, 0x3c, 0x4d, 0xc2, 0xf8, 0xe3, 0x0c, 0xea, 0xea, 0x2a, 0xfe, + 0x19, 0xef, 0x7c, 0x60, 0x6f, 0x60, 0x84, 0x41, 0x69, 0x04, 0x7e, 0x6c, + 0x7e, 0xb9, 0x92, 0x79, 0xaa, 0xbe, 0xf2, 0x4c, 0x60, 0xe9, 0x2d, 0x20, + 0x85, 0x7b, 0x75, 0xbc, 0xca, 0xb6, 0x7b, 0x16, 0x23, 0x12, 0x37, 0x6a, + 0x6c, 0xc2, 0xe7, 0x98, 0x3a, 0x5f, 0x00, 0xe9, 0x85, 0x5e, 0x5f, 0x20, + 0x8c, 0xf0, 0xdc, 0xe3, 0x9b, 0x0f, 0x4b, 0x02, 0x61, 0x81, 0x39, 0x0e, + 0xa5, 0x20, 0xfd, 0xbc, 0x57, 0xc5, 0xff, 0x38, 0xb0, 0x4e, 0xc1, 0x34, + 0xd3, 0x4c, 0xbf, 0xb3, 0xa8, 0x8e, 0xb7, 0x5a, 0xd2, 0x4b, 0xe0, 0x6c, + 0xc6, 0x39, 0x46, 0xfc, 0xd6, 0x6d, 0x57, 0xb8, 0xe9, 0x01, 0xd4, 0xfd, + 0xc4, 0xa7, 0xb9, 0x3b, 0xe8, 0x88, 0x74, 0x83, 0xf4, 0x54, 0xaf, 0x69, + 0x4a, 0x09, 0xd0, 0xf3, 0x6b, 0xdf, 0xee, 0x63, 0xc1, 0x9b, 0x03, 0xf2, + 0xb1, 0x5e, 0x95, 0x88, 0x1c, 0xfd, 0x54, 0x95, 0x6f, 0x0f, 0xd6, 0xf3, + 0x5e, 0xef, 0xc3, 0x81, 0x8f, 0x38, 0x95, 0xf8, 0x5d, 0x7f, 0x1b, 0x5d, + 0xd3, 0xd0, 0x6b, 0x55, 0x83, 0xf4, 0xe3, 0xde, 0x99, 0xbe, 0x48, 0x80, + 0x11, 0xef, 0x36, 0x13, 0x3e, 0xd7, 0x7b, 0xa7, 0xdf, 0xe3, 0x5b, 0x1c, + 0x38, 0xb5, 0x7c, 0x3b, 0x6a, 0x01, 0xa7, 0xeb, 0xcc, 0x2b, 0xf0, 0xdd, + 0x7d, 0xa4, 0xd7, 0x52, 0xff, 0xf3, 0xde, 0x85, 0x06, 0xb6, 0x38, 0xb3, + 0xbb, 0x55, 0x3f, 0xb5, 0xec, 0x4f, 0xf0, 0x02, 0xb7, 0x3f, 0xa0, 0x2a, + 0x7a, 0x4c, 0x28, 0x44, 0x0e, 0xb0, 0xcd, 0xb4, 0xc3, 0x53, 0x5b, 0x99, + 0x82, 0x78, 0xb9, 0x84, 0x36, 0xc7, 0x61, 0xff, 0xdb, 0xfe, 0xfb, 0xa3, + 0xd9, 0xc5, 0x4c, 0x37, 0x81, 0x25, 0x65, 0x7f, 0x8f, 0xde, 0x81, 0x2e, + 0x73, 0xca, 0xea, 0xb2, 0x8b, 0xd1, 0x83, 0xf6, 0x6a, 0xd8, 0x2a, 0x30, + 0xdd, 0xa7, 0x52, 0x1e, 0x2a, 0x3b, 0x1b, 0x2d, 0x9a, 0xfb, 0x7d, 0xfb, + 0x7e, 0xe1, 0x54, 0x77, 0xab, 0xf1, 0x91, 0xb2, 0xbf, 0x44, 0x1b, 0x03, + 0x8f, 0x09, 0x2a, 0x49, 0x08, 0xb4, 0x7b, 0x23, 0x42, 0x5f, 0xf7, 0x3b, + 0x81, 0x53, 0x51, 0x95, 0x0d, 0x6d, 0x61, 0x2f, 0xa5, 0x86, 0xde, 0x40, + 0xfa, 0x44, 0x93, 0x42, 0x0f, 0x10, 0xb9, 0x01, 0xa9, 0xe1, 0x67, 0x81, + 0x7d, 0x5c, 0x9f, 0xff, 0x87, 0xfe, 0x9a, 0x5a, 0x43, 0x6d, 0x56, 0xf5, + 0x24, 0xaf, 0x8c, 0x14, 0xf8, 0x2d, 0xff, 0x3f, 0x2f, 0xc3, 0x44, 0x5d, + 0xcf, 0x37, 0x94, 0xd8, 0x16, 0xe8, 0x46, 0x1e, 0x9e, 0x16, 0x65, 0x41, + 0x88, 0xba, 0x03, 0xba, 0x9b, 0xc9, 0x8c, 0x97, 0x04, 0x90, 0x67, 0x47, + 0xe7, 0x46, 0xd9, 0x1b, 0xe6, 0x83, 0x05, 0xfb, 0xc6, 0x15, 0x65, 0x9e, + 0x19, 0x88, 0x6a, 0x7d, 0x9f, 0x72, 0x13, 0x53, 0x26, 0xaa, 0xea, 0xa3, + 0x2d, 0x1a, 0xb0, 0xed, 0xc5, 0xe7, 0x0e, 0x54, 0x19, 0x3f, 0x49, 0x05, + 0x5b, 0x13, 0xba, 0xd3, 0x4d, 0x00, 0x6e, 0x9f, 0x39, 0x40, 0xca, 0x6e, + 0x92, 0x73, 0xfc, 0x5a, 0xc7, 0x78, 0x94, 0x10, 0xe3, 0x3c, 0xd9, 0x02, + 0x23, 0xe9, 0xdc, 0x3d, 0xd6, 0x8b, 0x5c, 0x9d, 0xf9, 0x69, 0xcb, 0x44, + 0xf5, 0xc4, 0x54, 0x8a, 0x73, 0x55, 0x33, 0x89, 0xe9, 0xfb, 0xbc, 0x39, + 0x5a, 0xf9, 0xa6, 0x3c, 0x55, 0x8b, 0xb2, 0x4e, 0xb3, 0x50, 0x25, 0xea, + 0xa6, 0x72, 0x5c, 0x41, 0x0d, 0x58, 0x17, 0x04, 0x96, 0x98, 0x17, 0x20, + 0xb5, 0x38, 0x7c, 0xb7, 0x98, 0xc7, 0x78, 0x77, 0x23, 0x87, 0xc2, 0xfe, + 0x90, 0xab, 0xa2, 0x8c, 0x98, 0xee, 0x1c, 0xd3, 0x5d, 0xe7, 0x57, 0x39, + 0xac, 0x3e, 0x31, 0x80, 0x7d, 0xef, 0x85, 0x48, 0xab, 0x25, 0x2c, 0x90, + 0xe3, 0xe9, 0x25, 0x79, 0x67, 0x28, 0x7d, 0x4e, 0xe9, 0x2b, 0xb9, 0xac, + 0x12, 0x2f, 0x58, 0x44, 0x2e, 0xb3, 0x66, 0x81, 0xff, 0xb5, 0xa8, 0xd6, + 0xce, 0x88, 0xc6, 0x8a, 0x1d, 0xde, 0xb5, 0x68, 0x25, 0xaa, 0xed, 0x16, + 0xef, 0x3a, 0xff, 0xe7, 0xdc, 0xed, 0x88, 0x83, 0x74, 0x27, 0x74, 0xdb, + 0xa2, 0x65, 0x08, 0x89, 0xae, 0x0c, 0xc7, 0x7f, 0xbf, 0x25, 0x4a, 0x1c, + 0x9a, 0x2a, 0x10, 0x1f, 0x45, 0x4a, 0xaf, 0xf7, 0x83, 0x78, 0x81, 0xdb, + 0xe2, 0x9f, 0x70, 0xb9, 0xab, 0x92, 0xb6, 0x8b, 0xb6, 0x8f, 0xb6, 0x37, + 0xc9, 0xfb, 0xd7, 0x0c, 0x51, 0x3e, 0x36, 0xf5, 0x6b, 0x59, 0xb0, 0xe2, + 0x6b, 0x3f, 0x5a, 0x25, 0xd8, 0xe2, 0x6c, 0xd8, 0x71, 0x64, 0x8f, 0xc0, + 0x9e, 0xa6, 0xfb, 0x87, 0xd6, 0x73, 0x79, 0x30, 0x91, 0xcf, 0x8c, 0x64, + 0x3f, 0x93, 0x15, 0xb4, 0xf1, 0x2a, 0xc7, 0x33, 0xde, 0xca, 0xeb, 0xb4, + 0x52, 0x05, 0xdc, 0x52, 0xb1, 0x48, 0xf0, 0xcd, 0x34, 0xb5, 0x92, 0xe9, + 0xef, 0x71, 0xa6, 0xb0, 0xfe, 0x10, 0x1b, 0xd6, 0x1d, 0x52, 0x85, 0xb3, + 0x44, 0x68, 0x66, 0xc2, 0x26, 0xd1, 0x01, 0x24, 0xec, 0x06, 0x26, 0xb6, + 0xbd, 0x5f, 0x0d, 0xb3, 0xaf, 0x63, 0xe4, 0x0c, 0xb1, 0x47, 0x5b, 0x7c, + 0xd2, 0x24, 0x7e, 0xcc, 0x69, 0xc3, 0x95, 0xd7, 0x65, 0xcb, 0xce, 0x90, + 0x0b, 0xf5, 0x49, 0xba, 0x9a, 0xdc, 0x06, 0x65, 0x30, 0x14, 0xcf, 0x18, + 0x86, 0x62, 0x16, 0x69, 0xcb, 0x14, 0x11, 0x2d, 0x59, 0xc8, 0xab, 0xb2, + 0x44, 0x6d, 0xc4, 0x1a, 0x38, 0x8e, 0xa9, 0xbf, 0x49, 0x93, 0x18, 0x52, + 0xe6, 0xf0, 0x45, 0x7d, 0xd8, 0xe5, 0xd0, 0x8b, 0xda, 0xd6, 0x1d, 0x82, + 0xe6, 0x78, 0x31, 0xe8, 0xc5, 0x31, 0x91, 0x25, 0xd6, 0x2c, 0x3f, 0x5d, + 0x6b, 0xb2, 0x28, 0x47, 0xbf, 0xd3, 0x12, 0x8c, 0x45, 0x63, 0x1d, 0x5b, + 0x72, 0x7e, 0x78, 0x44, 0x15, 0xa6, 0x33, 0x45, 0x4e, 0x9e, 0x09, 0xa2, + 0x86, 0x77, 0x7a, 0x8e, 0xc0, 0xb8, 0x57, 0x04, 0xf5, 0x13, 0xca, 0xce, + 0x1a, 0xc6, 0xb3, 0x87, 0xfe, 0x96, 0x6b, 0x83, 0x69, 0x40, 0x9e, 0x1c, + 0x8a, 0x7f, 0xd5, 0x4f, 0x6e, 0x76, 0x95, 0x61, 0x0d, 0xc1, 0x69, 0xc0, + 0xec, 0x1a, 0x8a, 0x7f, 0xd6, 0xcf, 0x88, 0x2c, 0xd4, 0x3b, 0x3f, 0x3b, + 0x43, 0x44, 0xd7, 0xe4, 0x48, 0x5e, 0x16, 0xa8, 0x5a, 0xb3, 0x83, 0xec, + 0x7e, 0xad, 0xab, 0x45, 0x48, 0xeb, 0x66, 0x0f, 0x69, 0xdd, 0x74, 0x5e, + 0x87, 0x45, 0x97, 0xde, 0xd5, 0xc5, 0x11, 0xb1, 0xcb, 0xa2, 0x12, 0x39, + 0xce, 0x63, 0xa5, 0xeb, 0x44, 0x39, 0xd4, 0xeb, 0x74, 0x41, 0x52, 0x16, + 0x8d, 0xba, 0xf8, 0x8b, 0xdc, 0xa1, 0x60, 0x71, 0xee, 0x27, 0xc1, 0x7f, + 0x22, 0x34, 0x4f, 0x1c, 0x31, 0x82, 0xae, 0xd9, 0xf2, 0xb4, 0x3e, 0xac, + 0x45, 0x4e, 0xdd, 0x3a, 0xa2, 0x42, 0x33, 0x30, 0x25, 0x4c, 0x62, 0x37, + 0xf6, 0x01, 0x9f, 0x19, 0xe6, 0xbf, 0xaf, 0x75, 0xe4, 0x01, 0x1f, 0x48, + 0x6d, 0x32, 0x86, 0x8d, 0xad, 0xce, 0xc0, 0x51, 0xf5, 0xec, 0x93, 0x22, + 0x17, 0xf6, 0x5a, 0x40, 0x57, 0x5e, 0xea, 0xa7, 0xe7, 0xcc, 0xef, 0x5b, + 0x7a, 0x61, 0x29, 0x71, 0xb4, 0xad, 0xbc, 0xb4, 0xd2, 0x10, 0x5e, 0x01, + 0x4b, 0x74, 0x69, 0x61, 0x43, 0xcb, 0x7e, 0x5f, 0x5a, 0xeb, 0x7c, 0x61, + 0x28, 0xfe, 0x14, 0x62, 0xa5, 0x4c, 0x26, 0x8e, 0xe7, 0x7c, 0x86, 0x96, + 0x64, 0xc8, 0x06, 0x0c, 0x29, 0x56, 0x70, 0x5b, 0x02, 0x86, 0x96, 0xa1, + 0xf8, 0x8a, 0x21, 0x3a, 0x3b, 0xc6, 0xc3, 0x44, 0x87, 0xd7, 0x6d, 0x09, + 0x8a, 0x73, 0x67, 0x4f, 0x82, 0x53, 0x91, 0xb9, 0x2a, 0xde, 0x18, 0xe1, + 0x6b, 0x89, 0x3b, 0x82, 0x3a, 0xa9, 0xc3, 0x6f, 0x08, 0xeb, 0x45, 0x94, + 0x2a, 0xe1, 0xa9, 0xa0, 0x13, 0xb3, 0x0e, 0x42, 0xec, 0x4a, 0x3f, 0xf2, + 0x12, 0x69, 0x4f, 0x2f, 0xdd, 0xaf, 0x3d, 0x06, 0x5b, 0xa6, 0x75, 0xbf, + 0x12, 0x35, 0x44, 0x9c, 0x68, 0x39, 0x95, 0xd0, 0xd5, 0x63, 0x43, 0xca, + 0x3c, 0xd0, 0x44, 0xd5, 0xe9, 0xab, 0xa5, 0xfe, 0x10, 0x4b, 0x3d, 0x79, + 0xea, 0x87, 0x73, 0x8f, 0x47, 0x6d, 0x68, 0x5f, 0xd5, 0x07, 0x76, 0x7a, + 0xd3, 0x76, 0x2e, 0xce, 0x99, 0x2d, 0x6b, 0xdd, 0xf5, 0xfe, 0x46, 0xac, + 0xa9, 0x07, 0xb2, 0xbc, 0xe0, 0xd0, 0x34, 0x67, 0x1e, 0x54, 0x37, 0x67, + 0x1c, 0x54, 0x35, 0xf3, 0x0e, 0xdd, 0x01, 0xde, 0x4f, 0xc2, 0xf5, 0x81, + 0xf9, 0x1c, 0x72, 0x3a, 0xac, 0xd7, 0x09, 0x86, 0x08, 0xfb, 0x64, 0x22, + 0xfe, 0xdb, 0x91, 0x34, 0x51, 0x0d, 0x19, 0xad, 0xb3, 0x9d, 0x3a, 0xf9, + 0xbd, 0x1c, 0xa6, 0xa7, 0x3e, 0xd0, 0x2a, 0x54, 0x9e, 0x45, 0x5a, 0xaa, + 0xe8, 0x69, 0xcf, 0x83, 0x7b, 0x27, 0x15, 0x74, 0xd3, 0xf9, 0x77, 0x32, + 0x6d, 0x9e, 0x2b, 0x63, 0x67, 0x22, 0x6e, 0x48, 0x64, 0x46, 0x0c, 0x4d, + 0x59, 0x1c, 0xb6, 0xa4, 0x94, 0x39, 0xe3, 0x08, 0x1c, 0xd3, 0x92, 0x93, + 0xc4, 0xcd, 0xd7, 0xf2, 0xbc, 0xee, 0xa0, 0xc8, 0xd1, 0xd3, 0xe0, 0x41, + 0xde, 0x19, 0xbd, 0x0a, 0xe5, 0xe3, 0xd1, 0xb4, 0xc8, 0xec, 0xd2, 0x57, + 0x64, 0x70, 0xbe, 0x2c, 0x13, 0xf7, 0x2f, 0xa2, 0xcb, 0x26, 0x59, 0xe5, + 0x7a, 0xd4, 0xff, 0x53, 0xcf, 0xda, 0x6b, 0xa9, 0x0e, 0x42, 0xf3, 0x33, + 0x98, 0x7f, 0x11, 0x67, 0xaf, 0xcd, 0x10, 0xdb, 0xee, 0x05, 0xde, 0x10, + 0x3e, 0xa5, 0x7c, 0xa3, 0x47, 0x5b, 0x3a, 0x90, 0x81, 0x1c, 0x34, 0x92, + 0xe3, 0xa8, 0xfd, 0x67, 0xf4, 0x3e, 0x3e, 0x0f, 0x32, 0xc4, 0x4c, 0xe4, + 0xcf, 0x9a, 0x1e, 0x47, 0x80, 0xaf, 0x3d, 0xa6, 0x8d, 0x2a, 0xb5, 0x5e, + 0x8c, 0x12, 0x3b, 0xea, 0xa0, 0x67, 0xaa, 0xb9, 0xa3, 0x96, 0xf9, 0xdc, + 0xdf, 0xa3, 0x8e, 0xc0, 0x02, 0xb5, 0xee, 0x04, 0xdf, 0x50, 0x4a, 0x57, + 0xda, 0xb5, 0xea, 0x9f, 0xde, 0x3f, 0xdb, 0x9b, 0x53, 0x22, 0xdf, 0x11, + 0xbd, 0x77, 0x12, 0x74, 0x7f, 0xd2, 0xbb, 0x77, 0xe5, 0xb9, 0x95, 0xb4, + 0x97, 0x86, 0xe2, 0xcd, 0x83, 0x50, 0x3c, 0x19, 0x2d, 0xe6, 0xa9, 0x70, + 0x43, 0xcd, 0xd5, 0x74, 0x20, 0x7b, 0xa2, 0xc9, 0x3a, 0x98, 0x1e, 0x3e, + 0xd0, 0xa3, 0x4d, 0x3d, 0xa9, 0x7f, 0x7a, 0x2a, 0xa4, 0x8a, 0x29, 0x11, + 0x5d, 0xeb, 0xfe, 0xd9, 0x50, 0x48, 0x53, 0x5c, 0x17, 0xcd, 0x44, 0xfd, + 0xe1, 0x90, 0x60, 0x38, 0xc3, 0x07, 0x44, 0x2d, 0x9c, 0xcc, 0x3e, 0x97, + 0x25, 0xf6, 0x06, 0x5a, 0x04, 0xe8, 0x29, 0x88, 0x72, 0xe0, 0x88, 0xe2, + 0x28, 0xe4, 0x95, 0x9a, 0xf7, 0x58, 0xca, 0x8f, 0x28, 0x65, 0x8e, 0x8d, + 0x92, 0x29, 0x17, 0xb1, 0x5c, 0x70, 0x56, 0x9c, 0xa1, 0x71, 0x56, 0x5a, + 0xdf, 0x9e, 0x64, 0x9c, 0x4e, 0xa9, 0x2f, 0xcb, 0xcb, 0xc8, 0xb4, 0xbe, + 0x93, 0x27, 0x53, 0xc5, 0xa9, 0x40, 0x6b, 0xbb, 0x1a, 0xdf, 0x77, 0x99, + 0xe2, 0x23, 0x43, 0x34, 0x44, 0x96, 0x08, 0xc8, 0xaf, 0xce, 0x64, 0x8a, + 0xcd, 0xff, 0xa1, 0x86, 0x4b, 0x97, 0x0d, 0x28, 0xeb, 0x3e, 0x52, 0xbe, + 0xcf, 0xfc, 0x63, 0xe3, 0x6e, 0xd4, 0xaf, 0xf6, 0xe2, 0xf3, 0x1c, 0x3e, + 0xfb, 0xf1, 0x39, 0x8c, 0x4f, 0x66, 0xa4, 0x6d, 0x95, 0xa1, 0x19, 0xad, + 0xce, 0xb3, 0x86, 0xb0, 0x01, 0x21, 0xb9, 0xe9, 0x0c, 0xf0, 0x48, 0xd1, + 0x62, 0x8f, 0xb7, 0x67, 0x5c, 0x7a, 0xb8, 0x6d, 0x55, 0x7a, 0xc4, 0x88, + 0xbe, 0x2c, 0x8f, 0x31, 0x72, 0xdc, 0x92, 0x86, 0xed, 0xbf, 0xfe, 0x4c, + 0x12, 0x0f, 0x1e, 0x05, 0x0f, 0x37, 0x9d, 0xc8, 0x8c, 0x18, 0xc5, 0x8c, + 0xd6, 0xe3, 0x96, 0xf9, 0x96, 0x6b, 0x4b, 0x99, 0x7e, 0x06, 0x7f, 0x0b, + 0x69, 0x19, 0x29, 0xe1, 0x8c, 0x48, 0xa6, 0x98, 0xd2, 0x2a, 0x5a, 0x0c, + 0x11, 0x83, 0x47, 0xb4, 0x1c, 0x12, 0xe0, 0xcc, 0xea, 0xff, 0x00, 0x69, + 0xd3, 0x65, 0x32, 0xe5, 0xef, 0x51, 0x83, 0x38, 0xda, 0x3b, 0x4a, 0x2b, + 0x7f, 0x2d, 0x3f, 0x76, 0xf9, 0x7f, 0xa6, 0x7c, 0xf8, 0x72, 0x1a, 0xb6, + 0x29, 0x2d, 0x7c, 0x24, 0xfa, 0xaf, 0x38, 0xf9, 0xb5, 0xbc, 0xfa, 0xb2, + 0x11, 0x43, 0x3e, 0xe2, 0x74, 0xad, 0x06, 0x31, 0xd9, 0x6f, 0xaf, 0xca, + 0x4b, 0x2f, 0x63, 0xaf, 0x38, 0x19, 0xc4, 0xaf, 0x45, 0x98, 0x8a, 0xbd, + 0x7a, 0x6d, 0xf9, 0x20, 0xdf, 0x79, 0xf9, 0xdf, 0xf1, 0x3a, 0xe7, 0xf2, + 0x37, 0x94, 0xf0, 0xa3, 0x01, 0x28, 0xce, 0x91, 0x33, 0xc5, 0xe5, 0x39, + 0xa4, 0xe2, 0x1b, 0x9a, 0x49, 0x97, 0xa7, 0xff, 0x07, 0xa8, 0x5c, 0x08, + 0x7f, 0xb2, 0xff, 0x63, 0x67, 0x1c, 0x60, 0x10, 0xe7, 0x95, 0xbf, 0x77, + 0x19, 0x0a, 0xbf, 0x8c, 0x96, 0xc2, 0xb9, 0x6b, 0x5a, 0x6b, 0x1e, 0x4d, + 0x6d, 0xc6, 0xd4, 0x17, 0x02, 0x59, 0x11, 0x8a, 0x8f, 0x7f, 0x9c, 0xf9, + 0xe8, 0x32, 0x5d, 0xad, 0xd7, 0x55, 0x19, 0xef, 0x18, 0x83, 0x9c, 0x7a, + 0x7b, 0x20, 0xa5, 0xc1, 0x08, 0xd0, 0x14, 0x16, 0xe0, 0x74, 0x16, 0x02, + 0xe2, 0xf4, 0x7b, 0xcb, 0x33, 0x43, 0x50, 0x4a, 0x24, 0xe2, 0x76, 0xfa, + 0x91, 0xb6, 0x34, 0xcc, 0x49, 0x67, 0x80, 0x41, 0xb7, 0x23, 0xa0, 0xe1, + 0xc7, 0x41, 0xbe, 0xc7, 0x22, 0x8c, 0x47, 0x8e, 0xe2, 0x75, 0x5b, 0x43, + 0xf4, 0x7c, 0x4f, 0x47, 0xa0, 0x59, 0xe3, 0x3a, 0x81, 0x75, 0xb6, 0x42, + 0x8b, 0x6e, 0x8f, 0x57, 0xa9, 0xb1, 0x50, 0xd2, 0xf0, 0xb6, 0x40, 0x69, + 0xe0, 0x5c, 0x00, 0xa5, 0xa2, 0x87, 0xc5, 0x31, 0xf4, 0x23, 0xcb, 0xc7, + 0xd8, 0x3b, 0xb9, 0x9e, 0xb6, 0x80, 0xa3, 0x01, 0xe9, 0xe7, 0xac, 0x68, + 0xf9, 0x94, 0x83, 0xf1, 0x9d, 0x82, 0x8d, 0xae, 0xfa, 0xea, 0x25, 0x37, + 0x5c, 0xc0, 0xd4, 0xa2, 0xe5, 0x55, 0xe1, 0xd8, 0x59, 0x0a, 0x7d, 0xb2, + 0xac, 0x24, 0xf4, 0x31, 0x99, 0xf2, 0xa1, 0x91, 0x4e, 0x97, 0xed, 0x1c, + 0xe7, 0x2d, 0xd3, 0x05, 0xed, 0xb0, 0x38, 0xe7, 0x96, 0x32, 0x7d, 0x68, + 0x1f, 0xe7, 0x2d, 0x67, 0xdc, 0x19, 0xc1, 0x37, 0xa2, 0xdf, 0xe4, 0x48, + 0x62, 0xe7, 0xb2, 0x44, 0x6e, 0x90, 0xa3, 0xca, 0x89, 0x70, 0xcd, 0x06, + 0xf0, 0x96, 0xeb, 0xc2, 0x9a, 0x26, 0x75, 0x73, 0x1a, 0xe8, 0xbf, 0x9f, + 0x29, 0x86, 0x4a, 0x0c, 0xdd, 0x75, 0x25, 0xc6, 0xee, 0x05, 0x25, 0x28, + 0x8f, 0xcf, 0x2d, 0xc4, 0xdf, 0xde, 0x5e, 0x64, 0x6b, 0xf2, 0xf4, 0x73, + 0x37, 0x80, 0x70, 0xc3, 0xb4, 0xa0, 0xa3, 0x57, 0x07, 0xf5, 0x53, 0xc7, + 0x14, 0xc7, 0xbb, 0xd5, 0xb1, 0x0b, 0xfd, 0xf4, 0x2b, 0xe0, 0x57, 0x89, + 0xe4, 0xff, 0x37, 0xae, 0x02, 0x72, 0x3b, 0x7c, 0xa1, 0xf8, 0xa6, 0x91, + 0xaf, 0x12, 0xb7, 0x2b, 0xae, 0x3e, 0xb8, 0x01, 0x2c, 0x01, 0xe1, 0x86, + 0x8c, 0x5c, 0xb3, 0x3f, 0x2b, 0x50, 0x11, 0x24, 0xfc, 0xf8, 0x73, 0x65, + 0x01, 0x4b, 0x40, 0xa7, 0x51, 0x9d, 0x4c, 0x86, 0xa9, 0x7b, 0xab, 0x34, + 0x1a, 0xc5, 0x0d, 0xfc, 0xf1, 0x7b, 0x72, 0xe0, 0xec, 0x38, 0x53, 0xef, + 0x56, 0x35, 0x7b, 0x35, 0xe4, 0x5b, 0x5f, 0x46, 0xf5, 0xea, 0xbf, 0x9f, + 0xd4, 0xda, 0xb5, 0xe5, 0xdb, 0xbd, 0x19, 0x90, 0x1d, 0xb8, 0x33, 0xa0, + 0x2b, 0xc3, 0x98, 0x89, 0xba, 0xd3, 0x74, 0xed, 0x23, 0x14, 0xde, 0x21, + 0x3c, 0x3d, 0xd3, 0x3d, 0xca, 0xcb, 0xc2, 0x3e, 0x36, 0x6c, 0xe0, 0x55, + 0xe1, 0xb1, 0xbd, 0x93, 0x03, 0x8d, 0xb6, 0xf1, 0x58, 0xb3, 0xd6, 0xc3, + 0x0a, 0x77, 0x4a, 0x50, 0x68, 0xca, 0xcd, 0x0e, 0x70, 0x7e, 0x9d, 0x63, + 0xbb, 0x4f, 0xd5, 0xcc, 0x86, 0xd7, 0x94, 0x10, 0x89, 0xa6, 0x73, 0x03, + 0x28, 0xf9, 0xd6, 0x07, 0x5e, 0xf2, 0x23, 0x47, 0xeb, 0x61, 0x1d, 0x65, + 0xc8, 0xa5, 0xcb, 0xfc, 0x0e, 0x28, 0xc5, 0x11, 0xaf, 0x7e, 0x06, 0x9c, + 0x9c, 0xa4, 0x12, 0xd5, 0xcf, 0xf4, 0x8c, 0xd3, 0x87, 0xe9, 0x19, 0x6b, + 0xaa, 0x88, 0x5e, 0x1c, 0x8c, 0xcb, 0x23, 0xac, 0x48, 0x66, 0x88, 0x77, + 0x39, 0xa0, 0x22, 0xe8, 0x84, 0x54, 0xd0, 0xb7, 0xb2, 0x8a, 0xd6, 0xfd, + 0xa9, 0xac, 0x12, 0xc3, 0xc2, 0x47, 0xa7, 0x50, 0xdf, 0x71, 0xea, 0x65, + 0x37, 0x8e, 0x4b, 0xcd, 0xc9, 0xf5, 0x81, 0x72, 0xec, 0x57, 0xe6, 0x8c, + 0x8b, 0x27, 0x33, 0x2a, 0x82, 0x6a, 0xb1, 0xc7, 0xea, 0xae, 0xd5, 0x89, + 0x65, 0x28, 0x55, 0x34, 0x2d, 0x5a, 0x31, 0xe5, 0x60, 0x22, 0xfe, 0xee, + 0x08, 0x95, 0x2a, 0xcf, 0x2a, 0x52, 0x85, 0x9e, 0x9c, 0xe7, 0x29, 0xb4, + 0x41, 0xb1, 0x67, 0x82, 0xa0, 0x96, 0x4c, 0xb9, 0x1c, 0xe2, 0xe7, 0x26, + 0xd8, 0xdd, 0xbe, 0x2f, 0xfa, 0xbc, 0x5a, 0x7d, 0x32, 0x3b, 0x37, 0x07, + 0xfd, 0x67, 0xda, 0xd5, 0x10, 0x89, 0x36, 0x62, 0xaa, 0x89, 0x84, 0xa6, + 0xd3, 0x49, 0x5a, 0x9b, 0xb6, 0x7c, 0xb3, 0xd7, 0x94, 0xc4, 0x8d, 0x8b, + 0xf3, 0xef, 0x88, 0xd2, 0x94, 0xd9, 0x81, 0x8f, 0xa2, 0xe5, 0x70, 0x4b, + 0x79, 0x46, 0x70, 0x6e, 0x4d, 0x19, 0x62, 0x23, 0x1d, 0xd8, 0x66, 0xad, + 0xc7, 0x12, 0x20, 0x42, 0xee, 0xd7, 0xf8, 0x78, 0x0f, 0x39, 0xbb, 0x8d, + 0x37, 0x63, 0x8b, 0x4d, 0x88, 0x0d, 0x1e, 0x9c, 0x5e, 0x90, 0xee, 0x8f, + 0x96, 0x07, 0x6c, 0x28, 0x01, 0xcb, 0xfd, 0x6b, 0xa8, 0xdc, 0x42, 0x3d, + 0xb2, 0xdc, 0x5f, 0x0e, 0x21, 0x3b, 0x2d, 0xe9, 0xc6, 0x9a, 0x53, 0x51, + 0x4f, 0x81, 0x0e, 0x6c, 0x1e, 0xfb, 0xd7, 0xf0, 0xed, 0x6e, 0xbf, 0x09, + 0x4e, 0x47, 0x1f, 0xff, 0x1a, 0x3e, 0x35, 0x9c, 0x69, 0x3f, 0x16, 0xa5, + 0xf5, 0x01, 0xd1, 0x7a, 0xc8, 0x7f, 0x80, 0xef, 0xad, 0x68, 0xb2, 0xf6, + 0xf3, 0x51, 0x4b, 0x60, 0x72, 0x20, 0x23, 0x37, 0xd8, 0x40, 0xe9, 0xa0, + 0x50, 0x43, 0x4e, 0x72, 0x7e, 0xa6, 0xf7, 0x5e, 0x0d, 0x7b, 0x92, 0x6b, + 0x04, 0x5e, 0xfd, 0x8c, 0xbb, 0xb6, 0x21, 0xfa, 0x9c, 0xfa, 0x8b, 0x93, + 0x5c, 0x30, 0x8e, 0x29, 0x29, 0x3d, 0x8c, 0x0b, 0xd0, 0xd5, 0xf9, 0xeb, + 0x02, 0x68, 0xa9, 0xf7, 0x51, 0xbd, 0xa7, 0xcb, 0x1a, 0xf4, 0xaf, 0x0f, + 0xb8, 0x6b, 0x31, 0x75, 0x24, 0x2b, 0x38, 0x3f, 0xea, 0x6e, 0x98, 0x0e, + 0xda, 0x56, 0x4d, 0x8b, 0x6e, 0xf7, 0x5e, 0x65, 0x7c, 0xdf, 0x81, 0x5a, + 0xaf, 0xa8, 0x1d, 0x77, 0x22, 0x45, 0x8c, 0x29, 0x12, 0xe0, 0x56, 0x94, + 0x00, 0x73, 0x10, 0x2b, 0x84, 0x57, 0x52, 0x3d, 0x6d, 0x2e, 0xbf, 0x2a, + 0x55, 0xc8, 0xe4, 0x2b, 0x81, 0x14, 0xe4, 0x03, 0x6d, 0xc8, 0x07, 0xa2, + 0x51, 0x28, 0xa0, 0x7c, 0xe0, 0xe7, 0xc8, 0x97, 0x5f, 0x27, 0xf4, 0xec, + 0xa1, 0x1d, 0x47, 0x90, 0x23, 0x34, 0xfd, 0xdc, 0x01, 0x36, 0x4d, 0x78, + 0x47, 0x20, 0x0d, 0x16, 0xe5, 0xcd, 0x07, 0x75, 0xd3, 0x4e, 0x41, 0x7d, + 0xea, 0x9e, 0x8a, 0x44, 0x85, 0x3a, 0x7c, 0x0f, 0x9f, 0x70, 0xbf, 0xe4, + 0x8f, 0xf1, 0xe5, 0x01, 0x2a, 0xd3, 0xdd, 0x7e, 0xa4, 0xab, 0x82, 0x1c, + 0x77, 0x3e, 0xbd, 0x13, 0x64, 0x97, 0x6e, 0x97, 0x76, 0x17, 0xec, 0x62, + 0x77, 0xb5, 0x07, 0xa0, 0xd4, 0x20, 0x39, 0x03, 0xd6, 0xd0, 0xad, 0xce, + 0x59, 0xdd, 0x1c, 0x78, 0x9c, 0x13, 0xba, 0x9d, 0x53, 0xdf, 0x68, 0x4f, + 0x2b, 0x29, 0x3d, 0x45, 0xd7, 0xec, 0xab, 0xa4, 0xf2, 0xc0, 0x73, 0xbe, + 0x2c, 0x8f, 0xdb, 0x8f, 0x76, 0x91, 0xb2, 0x1a, 0xbb, 0xbf, 0xf7, 0xb7, + 0x05, 0x4b, 0x41, 0x25, 0x3e, 0x83, 0x56, 0xc8, 0xdf, 0x7b, 0x09, 0xcf, + 0x84, 0x1f, 0x3b, 0xc7, 0x41, 0xed, 0xd4, 0xd4, 0xe2, 0xcb, 0x38, 0x0a, + 0x6d, 0x7d, 0x5b, 0xe0, 0x52, 0x82, 0xfe, 0xbf, 0x02, 0xfb, 0x14, 0xd7, + 0xb6, 0x51, 0xff, 0xa5, 0xc4, 0xbd, 0x30, 0x73, 0xea, 0xc7, 0xd1, 0xb4, + 0xe2, 0x63, 0x98, 0xce, 0xd8, 0xe7, 0x03, 0x39, 0xe1, 0x83, 0x16, 0xfc, + 0xb5, 0x81, 0xe7, 0x7f, 0xfc, 0xaf, 0x76, 0xea, 0xbb, 0xfd, 0xce, 0x63, + 0xdd, 0x77, 0x38, 0xbf, 0x27, 0x2d, 0x72, 0xfe, 0x5a, 0xd6, 0x4e, 0xf8, + 0xa5, 0xac, 0x2b, 0x98, 0xd0, 0x7b, 0xbf, 0xf3, 0x01, 0x69, 0x83, 0x33, + 0x2e, 0x1d, 0x89, 0x96, 0x05, 0xde, 0x55, 0xe7, 0x9c, 0x6c, 0xe4, 0x5b, + 0xbd, 0x20, 0x96, 0xf9, 0xd1, 0xc2, 0x0a, 0xab, 0x15, 0x78, 0x11, 0xca, + 0x72, 0x75, 0xb8, 0xdd, 0xff, 0x52, 0x80, 0x54, 0xbc, 0xe4, 0x77, 0x37, + 0x10, 0xb7, 0xbb, 0x76, 0x05, 0xba, 0x57, 0xe0, 0x58, 0x82, 0x33, 0x3f, + 0xe8, 0x75, 0x06, 0x28, 0xa7, 0xdc, 0x1c, 0x65, 0x22, 0x99, 0x66, 0x28, + 0x7d, 0x5c, 0x5e, 0x85, 0x74, 0x68, 0xf0, 0x94, 0xfb, 0x91, 0x0b, 0xdc, + 0x70, 0x31, 0xda, 0x68, 0x2f, 0x0f, 0x18, 0x84, 0x4d, 0xd2, 0x76, 0xef, + 0x97, 0x98, 0x02, 0x4a, 0xd3, 0x65, 0x50, 0x7e, 0xcb, 0x03, 0xbd, 0x76, + 0x13, 0x1c, 0x05, 0x9d, 0x67, 0xab, 0xa0, 0x93, 0x6b, 0xab, 0x69, 0x0e, + 0xe2, 0x60, 0x9a, 0x2f, 0x60, 0x2a, 0xa6, 0x74, 0x91, 0x44, 0x26, 0x30, + 0x12, 0x3b, 0x81, 0xae, 0x44, 0xa2, 0x7b, 0xbd, 0xba, 0x31, 0x94, 0xa0, + 0x95, 0x78, 0x77, 0x94, 0x71, 0x7c, 0x12, 0xa5, 0x67, 0xac, 0xd2, 0x52, + 0x40, 0x5a, 0x18, 0xbd, 0xb6, 0x1c, 0x90, 0xee, 0x88, 0xde, 0x56, 0x4d, + 0x26, 0xd3, 0xb2, 0x5e, 0x8f, 0x0e, 0xdb, 0xcf, 0xe7, 0x19, 0x04, 0xba, + 0x63, 0xe0, 0x6c, 0x94, 0xc1, 0x92, 0x66, 0x44, 0x55, 0x05, 0x2f, 0x47, + 0x35, 0xe8, 0x9a, 0x1e, 0xd5, 0x16, 0xbc, 0x88, 0x39, 0x77, 0xaa, 0xe1, + 0xc4, 0xe4, 0xa8, 0x57, 0xa9, 0x1b, 0x22, 0x6c, 0xf3, 0xf3, 0xd1, 0xbd, + 0xf6, 0x46, 0x5b, 0x79, 0xe0, 0x28, 0x64, 0x78, 0xba, 0x60, 0x13, 0x5a, + 0xf0, 0x0c, 0xda, 0x2d, 0x7c, 0x14, 0x5a, 0x29, 0x8f, 0x2c, 0x8a, 0xee, + 0x54, 0xb3, 0x27, 0xa0, 0x95, 0x6d, 0xd1, 0x3d, 0xa5, 0xb7, 0x68, 0x77, + 0x4e, 0xc6, 0x7c, 0x5d, 0x68, 0xe7, 0xd1, 0x91, 0x83, 0x82, 0xa3, 0xf9, + 0x07, 0x51, 0x95, 0x63, 0x4f, 0xb4, 0x0b, 0x6d, 0xf3, 0x12, 0xb8, 0xb2, + 0x90, 0xb4, 0xd0, 0xd3, 0xe9, 0x40, 0xfe, 0xea, 0xb2, 0x2a, 0x4a, 0x66, + 0xb8, 0x17, 0x95, 0xc2, 0xb4, 0x10, 0x0d, 0x43, 0xfc, 0x55, 0xb8, 0x6b, + 0xb5, 0xd1, 0xfa, 0x3c, 0x8d, 0x33, 0xad, 0x9b, 0x79, 0x8a, 0x99, 0x60, + 0x3b, 0x75, 0xc1, 0xda, 0xd3, 0xae, 0x0e, 0x33, 0xa2, 0x3a, 0x22, 0x72, + 0x3d, 0xed, 0x2a, 0xe7, 0xf8, 0x6e, 0xd5, 0x8d, 0x17, 0xdb, 0x67, 0x58, + 0xdd, 0x81, 0xd3, 0xea, 0x3b, 0x4e, 0x2e, 0x51, 0xdf, 0x70, 0xf2, 0x6b, + 0x0a, 0xe9, 0xfe, 0xec, 0xf2, 0xff, 0x2c, 0xed, 0x9f, 0xd1, 0x6f, 0xe2, + 0xff, 0xf6, 0x1f, 0xe3, 0xe9, 0x0a, 0x32, 0x52, 0x61, 0x0e, 0x31, 0xe1, + 0xdf, 0x22, 0x7c, 0x14, 0x3a, 0x7d, 0xf8, 0x6a, 0xec, 0x9b, 0x54, 0x5f, + 0x19, 0x49, 0x24, 0x36, 0xd2, 0xa7, 0x0f, 0x9f, 0xe1, 0x44, 0xc2, 0xdd, + 0xf0, 0x48, 0x9e, 0x3d, 0x44, 0x63, 0xef, 0x2d, 0x31, 0x4a, 0xb7, 0x94, + 0x18, 0xa4, 0x64, 0x3e, 0x2c, 0x45, 0x29, 0xf5, 0xb5, 0x3c, 0x52, 0x61, + 0x0f, 0xb9, 0x6b, 0x69, 0x68, 0xe9, 0x68, 0x6b, 0xc7, 0x43, 0x79, 0xc0, + 0xc4, 0x67, 0x80, 0xd9, 0xc3, 0xec, 0xb4, 0x08, 0x0b, 0xe5, 0x2e, 0x7e, + 0x5a, 0x50, 0x19, 0x29, 0x9e, 0x46, 0xc7, 0x31, 0x08, 0x0b, 0xb9, 0x32, + 0x2b, 0x62, 0xaf, 0xb5, 0x46, 0x2c, 0x3b, 0x84, 0x02, 0xd4, 0xd1, 0x55, + 0xca, 0xdd, 0x33, 0xc1, 0x3e, 0x8d, 0x98, 0x0a, 0x65, 0x01, 0x16, 0xac, + 0x81, 0xed, 0xda, 0xc2, 0x93, 0x96, 0x5c, 0x4d, 0xab, 0xc1, 0x6f, 0x0d, + 0xe4, 0xf8, 0xef, 0xf6, 0x5f, 0x41, 0xca, 0xba, 0xe2, 0x67, 0x5a, 0xa8, + 0x7d, 0xa3, 0x45, 0x5a, 0xbc, 0x28, 0xe9, 0x44, 0x26, 0xb2, 0x28, 0x87, + 0xb4, 0x18, 0x78, 0x12, 0x7b, 0xb1, 0x5f, 0x2b, 0xea, 0x9e, 0x79, 0xd3, + 0xe2, 0x86, 0xa0, 0x3b, 0xe1, 0x7e, 0x46, 0x60, 0x8e, 0xdf, 0x00, 0x6b, + 0x6e, 0x48, 0xdc, 0x30, 0x15, 0xd2, 0xab, 0x21, 0xb6, 0xa7, 0xff, 0x4f, + 0x51, 0x4b, 0x6e, 0xb5, 0xf6, 0xaf, 0x27, 0x34, 0xad, 0x36, 0x30, 0xf8, + 0xf3, 0x03, 0x54, 0x8e, 0x94, 0xc0, 0x60, 0xfc, 0x91, 0x11, 0x7a, 0xeb, + 0x86, 0xb6, 0x0a, 0x62, 0xbf, 0xe9, 0x9b, 0xea, 0xff, 0x63, 0xd4, 0xa6, + 0x84, 0xb2, 0x89, 0xbe, 0x28, 0xf0, 0x1e, 0xb4, 0x19, 0x25, 0x92, 0x3c, + 0x6b, 0x29, 0xed, 0xe5, 0x71, 0x1d, 0x6c, 0x1e, 0x2b, 0x6d, 0xa1, 0xab, + 0xfe, 0xe5, 0x91, 0xf8, 0xdf, 0x87, 0x35, 0x87, 0x6c, 0xa0, 0x8e, 0x3c, + 0x1b, 0x20, 0x61, 0x55, 0xec, 0xb7, 0x89, 0xbc, 0xd1, 0x9b, 0x9c, 0xd2, + 0x5f, 0xce, 0xea, 0xe8, 0x8f, 0x4f, 0x1d, 0xba, 0x36, 0xed, 0xf1, 0x61, + 0x35, 0xa6, 0x65, 0x47, 0xd3, 0xee, 0x4f, 0x8c, 0xc5, 0xb4, 0x2c, 0xa6, + 0x75, 0x75, 0xa8, 0x61, 0xdb, 0x11, 0x1d, 0xda, 0x66, 0x10, 0x7b, 0xb5, + 0xdf, 0x59, 0xc3, 0x1e, 0xd2, 0x34, 0x13, 0x07, 0x09, 0x33, 0xbc, 0xba, + 0xa9, 0x91, 0x63, 0x77, 0x69, 0x9b, 0x55, 0x4d, 0x4c, 0x18, 0x26, 0xaa, + 0xa5, 0x43, 0xca, 0xcc, 0x60, 0x31, 0x8c, 0xc4, 0x5f, 0x18, 0x3e, 0xd4, + 0x70, 0x38, 0x70, 0xd5, 0xf7, 0xd3, 0xe1, 0x3c, 0xdf, 0x6e, 0x61, 0xa2, + 0xbc, 0x32, 0xd0, 0xb6, 0x1a, 0x25, 0xcf, 0x89, 0xb6, 0x6d, 0xa2, 0x5a, + 0x75, 0xc2, 0x06, 0x0b, 0x5d, 0x6c, 0x8c, 0x0c, 0x1b, 0xf9, 0xf3, 0xf7, + 0x34, 0xf2, 0x22, 0xb1, 0x08, 0x6a, 0x39, 0xcb, 0xdb, 0xb6, 0x69, 0xdf, + 0xea, 0x6c, 0xe4, 0x35, 0x6d, 0xcb, 0xe8, 0x39, 0x9f, 0xe4, 0x20, 0x13, + 0x3b, 0x3a, 0x60, 0x28, 0x54, 0xee, 0x9d, 0x2a, 0x5c, 0x25, 0xfc, 0xcf, + 0xfc, 0x97, 0x86, 0xd0, 0xa6, 0x3c, 0xe2, 0xea, 0xd4, 0x61, 0x0d, 0x44, + 0x3e, 0x1c, 0xf8, 0x53, 0x54, 0x83, 0xae, 0x3f, 0xc8, 0x9f, 0x04, 0xde, + 0x45, 0x1a, 0xa1, 0xe7, 0x49, 0xd1, 0xbb, 0x73, 0xe8, 0xcc, 0xfb, 0xd5, + 0xfb, 0x73, 0xe8, 0x2c, 0x5c, 0x7f, 0xfc, 0x37, 0x83, 0xf4, 0x14, 0xd1, + 0x9d, 0x74, 0x65, 0x29, 0x1f, 0xec, 0xd0, 0xcc, 0xa5, 0xb7, 0xc6, 0x39, + 0xfd, 0x83, 0xf1, 0xd0, 0x80, 0x37, 0x47, 0x25, 0x3b, 0x95, 0x9b, 0x19, + 0x78, 0x3f, 0x9d, 0x4f, 0xb7, 0xa5, 0x25, 0xcf, 0xac, 0x05, 0xe8, 0xda, + 0x18, 0xec, 0x98, 0xb5, 0x52, 0x0d, 0x30, 0xc1, 0x20, 0x37, 0xda, 0x47, + 0xe2, 0xb6, 0x91, 0xc0, 0x52, 0x7a, 0x9a, 0xa3, 0x0a, 0x1a, 0xdd, 0xa6, + 0xae, 0x16, 0x61, 0x48, 0xa6, 0x3b, 0x0d, 0x93, 0x67, 0x66, 0x25, 0x57, + 0x57, 0xa0, 0x36, 0x52, 0xc2, 0x9e, 0x1a, 0xcb, 0xab, 0xfc, 0x34, 0x54, + 0xdb, 0xeb, 0x5d, 0x49, 0xd7, 0x25, 0x1e, 0x80, 0x7b, 0x57, 0xae, 0xe2, + 0x8a, 0x03, 0x93, 0xb0, 0x7c, 0x7a, 0x57, 0x1f, 0x14, 0x7f, 0x29, 0x7d, + 0x36, 0x9a, 0xe3, 0xda, 0xf4, 0xc1, 0x4e, 0x9a, 0x9e, 0x95, 0xb6, 0x83, + 0xc8, 0x59, 0x90, 0x47, 0xeb, 0x64, 0x3a, 0x77, 0xbb, 0xa2, 0x0f, 0x29, + 0x5a, 0x59, 0x6b, 0x7e, 0x47, 0xdf, 0xa7, 0x51, 0xb0, 0x91, 0xd2, 0x8f, + 0xa4, 0xdb, 0x11, 0xe6, 0xb1, 0x3c, 0x71, 0xf1, 0xfe, 0x8b, 0x28, 0x21, + 0x8a, 0x21, 0xc7, 0xdf, 0x34, 0xdb, 0x06, 0x7f, 0xfb, 0xba, 0xcc, 0xe4, + 0xa9, 0xab, 0xc9, 0xf2, 0x32, 0xa5, 0xba, 0x95, 0x87, 0xe0, 0x18, 0x97, + 0x15, 0xa0, 0x3b, 0x11, 0xbe, 0x90, 0x18, 0xdb, 0xa2, 0x9c, 0x7f, 0x4a, + 0xc4, 0x45, 0x9c, 0x9f, 0x49, 0x34, 0x6f, 0xb6, 0xbf, 0x05, 0xf3, 0x7e, + 0x18, 0x4d, 0xae, 0x1f, 0xf8, 0x50, 0x3a, 0x17, 0x4d, 0x62, 0xcc, 0xae, + 0x60, 0xec, 0xb0, 0xf2, 0xb5, 0x82, 0x7e, 0x3f, 0xe8, 0x8f, 0x73, 0x83, + 0xa5, 0xca, 0x59, 0xac, 0xdb, 0x12, 0x74, 0x96, 0xbb, 0x3f, 0x6e, 0x1a, + 0xa4, 0x73, 0xb5, 0xc9, 0x79, 0xce, 0xfe, 0xb8, 0x5e, 0x49, 0xff, 0xdb, + 0x44, 0x72, 0xde, 0xfe, 0x2a, 0x8e, 0x33, 0x10, 0xcb, 0x6c, 0xac, 0x6c, + 0xe8, 0x5f, 0xb1, 0x6c, 0x4b, 0x9e, 0xf3, 0x1f, 0x1b, 0x33, 0x64, 0xea, + 0x34, 0xbe, 0x0c, 0x1d, 0xcf, 0x1c, 0x61, 0x76, 0x6a, 0x76, 0xea, 0xab, + 0x6d, 0x87, 0xb4, 0x3b, 0xd9, 0x9d, 0xba, 0x6a, 0xf6, 0x3d, 0xf5, 0x4e, + 0xe6, 0x00, 0xa5, 0xcb, 0x3f, 0x0f, 0x01, 0xcf, 0xa0, 0x44, 0xcd, 0x3f, + 0xa2, 0x7b, 0x8d, 0x41, 0xea, 0xa4, 0x76, 0x4b, 0x62, 0xa3, 0x8e, 0x49, + 0x24, 0xd2, 0x5e, 0x36, 0x75, 0x18, 0x6b, 0x9e, 0x39, 0x62, 0x3f, 0x64, + 0x7a, 0x4f, 0xdb, 0xcc, 0x36, 0x1b, 0x6a, 0x48, 0x58, 0xdd, 0xcc, 0x34, + 0x69, 0x9a, 0xfa, 0xe3, 0x6f, 0x0d, 0xa0, 0xc6, 0x29, 0x32, 0x07, 0x54, + 0xb1, 0x9f, 0x7f, 0x9d, 0xdf, 0x34, 0x3a, 0x16, 0xae, 0xe6, 0xa7, 0x67, + 0x75, 0xa7, 0x15, 0x56, 0x7f, 0x47, 0x15, 0xfb, 0x31, 0x5d, 0x9f, 0xd2, + 0x53, 0xbf, 0xca, 0xca, 0xd5, 0xdf, 0x1b, 0xec, 0x6c, 0xdb, 0xc6, 0xd4, + 0x20, 0x3d, 0x6e, 0xa2, 0xfb, 0x2e, 0x13, 0xff, 0x48, 0x24, 0xe8, 0xc9, + 0x33, 0x7d, 0x1d, 0xf9, 0xb0, 0x63, 0x5b, 0x72, 0x6f, 0x72, 0x0f, 0xea, + 0x17, 0x69, 0xfc, 0xd1, 0x7b, 0xc0, 0xc1, 0xf0, 0x4c, 0x6c, 0xfb, 0x48, + 0xdb, 0x36, 0x75, 0x4d, 0x31, 0xd0, 0x1c, 0xe5, 0x90, 0xc6, 0x9f, 0xbb, + 0xa7, 0x02, 0x48, 0x6c, 0x62, 0x5f, 0x5f, 0x27, 0xcd, 0x7b, 0xb5, 0x0e, + 0x26, 0xf6, 0x20, 0xa6, 0x13, 0x10, 0x07, 0x6a, 0xa5, 0xec, 0x60, 0x27, + 0x5d, 0x2f, 0x40, 0xa9, 0xdf, 0x7f, 0x6f, 0xdf, 0x68, 0x3d, 0xa6, 0x0e, + 0x5a, 0x2a, 0x89, 0xf1, 0xf4, 0x9b, 0x21, 0xff, 0xe6, 0x5d, 0x28, 0xdd, + 0x4a, 0x07, 0xe5, 0x85, 0x79, 0x94, 0x12, 0x93, 0xa7, 0x59, 0xaa, 0x62, + 0xea, 0x01, 0x98, 0x94, 0x2a, 0xad, 0xe0, 0x97, 0xc3, 0xfc, 0x54, 0xd1, + 0x02, 0x4e, 0xed, 0x59, 0x28, 0x50, 0xd5, 0x58, 0xd5, 0x4f, 0x73, 0x4e, + 0x64, 0xef, 0x83, 0xf1, 0x01, 0xba, 0x73, 0x03, 0x62, 0x33, 0x62, 0x1d, + 0xb9, 0xd8, 0x07, 0xcf, 0x1f, 0xb1, 0x85, 0x0f, 0xfb, 0xd4, 0x4d, 0xd6, + 0x80, 0x6e, 0x27, 0x07, 0xda, 0xb0, 0xb5, 0x39, 0x11, 0x3f, 0x96, 0x80, + 0x22, 0x7a, 0x92, 0xa4, 0x4e, 0xcc, 0x0f, 0xe7, 0x47, 0xb2, 0x42, 0x4e, + 0xe7, 0x42, 0x69, 0x56, 0x77, 0xaa, 0xf3, 0xa6, 0x6e, 0x1d, 0x3e, 0xe0, + 0x9c, 0x2d, 0x51, 0x6b, 0x0f, 0x1c, 0xf9, 0xa2, 0xa1, 0x59, 0x13, 0xb6, + 0x86, 0x5c, 0xd8, 0x63, 0x1b, 0x7b, 0x35, 0xa2, 0xad, 0x7c, 0x49, 0x28, + 0xec, 0x5d, 0x88, 0xbe, 0xd5, 0xbd, 0x69, 0x22, 0xf3, 0x04, 0x09, 0xdb, + 0x0e, 0x41, 0xf8, 0x89, 0x1a, 0xfb, 0x21, 0x75, 0x4b, 0xfe, 0x01, 0x26, + 0xf6, 0xfa, 0x80, 0x96, 0x57, 0x23, 0x95, 0xe4, 0x7a, 0x38, 0x94, 0x49, + 0x9a, 0x89, 0xd7, 0xc9, 0x1a, 0xb4, 0xc9, 0xf2, 0xc3, 0xb4, 0x34, 0xab, + 0xf2, 0x25, 0xdc, 0x2a, 0xe6, 0x47, 0x2c, 0x7e, 0x7a, 0xd2, 0x77, 0x8e, + 0xd4, 0xc8, 0x97, 0x83, 0x55, 0x33, 0xc8, 0xd1, 0xb3, 0x4c, 0x0a, 0x91, + 0x73, 0xda, 0x9c, 0x6f, 0xc9, 0xa4, 0x3c, 0xbf, 0xb9, 0x23, 0x3a, 0xd1, + 0xf9, 0x5b, 0x79, 0x42, 0x45, 0x5a, 0x78, 0x41, 0x4e, 0x7e, 0x78, 0x41, + 0x08, 0x50, 0x0b, 0xa0, 0x90, 0x5e, 0x2d, 0xe5, 0x8c, 0x4c, 0x4f, 0xbe, + 0xbe, 0x80, 0x5c, 0xf0, 0xd3, 0xa8, 0x0d, 0xa5, 0xab, 0x56, 0x9a, 0x62, + 0x77, 0xec, 0x57, 0xc5, 0x9e, 0x18, 0xb0, 0xb5, 0xaa, 0x5b, 0x98, 0xd8, + 0x0d, 0x23, 0x81, 0x3c, 0xb6, 0x58, 0xd3, 0xcd, 0xc6, 0xfe, 0x36, 0x98, + 0xa2, 0x1a, 0xcb, 0xa5, 0x80, 0x63, 0x0f, 0xff, 0x0c, 0xaf, 0xed, 0x3c, + 0x49, 0xd7, 0x10, 0xe4, 0x7b, 0x7f, 0x1d, 0xe5, 0xc5, 0x86, 0x9a, 0xe5, + 0xd5, 0x16, 0x8f, 0x5d, 0x74, 0xec, 0x59, 0xc2, 0x59, 0xd5, 0x16, 0xef, + 0x38, 0xf8, 0x2c, 0xba, 0xec, 0xb6, 0x4f, 0xa2, 0xa4, 0x68, 0xd9, 0x6d, + 0x0f, 0x0a, 0x1f, 0x46, 0xf3, 0xc5, 0xc5, 0x39, 0xf9, 0xcd, 0x4b, 0xb0, + 0xe5, 0xfd, 0x12, 0x38, 0xf7, 0xa2, 0x85, 0x68, 0x08, 0x23, 0x36, 0x1c, + 0x26, 0x84, 0x22, 0x3d, 0x9c, 0x12, 0xd6, 0x87, 0xf3, 0x5b, 0xd4, 0x21, + 0x27, 0xb8, 0x2a, 0x4e, 0xb5, 0xeb, 0x4b, 0xc6, 0x9f, 0x72, 0xa0, 0x9e, + 0xc7, 0xc6, 0xca, 0x51, 0x0b, 0x74, 0x4b, 0x60, 0x73, 0xc2, 0xa3, 0x95, + 0xfa, 0x88, 0xb1, 0x49, 0xd3, 0x6c, 0x73, 0x98, 0x61, 0xa7, 0x97, 0x9e, + 0xcf, 0xa0, 0xdd, 0x79, 0x0b, 0xea, 0x01, 0xef, 0x20, 0x16, 0x0d, 0x11, + 0x7a, 0x6e, 0xd2, 0x0e, 0x61, 0x97, 0x94, 0x2f, 0xea, 0xc2, 0x14, 0x3f, + 0x3a, 0x71, 0x09, 0xf6, 0xc1, 0x83, 0x92, 0x11, 0x26, 0x3a, 0x37, 0xc8, + 0xa4, 0x60, 0x5d, 0xaf, 0xbe, 0x55, 0x57, 0xa2, 0x3f, 0x93, 0xd2, 0x4a, + 0xcf, 0x41, 0xc1, 0xda, 0x44, 0x1c, 0xa9, 0x6e, 0xac, 0xb3, 0xe9, 0xad, + 0x68, 0xba, 0x12, 0x96, 0x1e, 0xfe, 0x02, 0x61, 0xd4, 0x47, 0x72, 0xcc, + 0xf9, 0xbb, 0x78, 0xb4, 0x02, 0xa7, 0x49, 0xb4, 0x36, 0x0b, 0xb8, 0xa6, + 0xeb, 0x4b, 0x33, 0x4f, 0x11, 0xc7, 0xae, 0xca, 0x37, 0x30, 0x9e, 0xb8, + 0xae, 0xb6, 0xa2, 0x4f, 0xb2, 0x40, 0xd9, 0x74, 0x5d, 0xe9, 0x8c, 0x6e, + 0x63, 0x13, 0xd8, 0xf2, 0x23, 0x9a, 0x26, 0x13, 0xa6, 0x9e, 0x99, 0xe3, + 0x9a, 0xee, 0x72, 0x8e, 0x91, 0x8c, 0xe2, 0x12, 0xce, 0x60, 0x37, 0x86, + 0x35, 0xe2, 0xdb, 0x5c, 0x9b, 0x30, 0x46, 0xd6, 0xb4, 0x62, 0xbf, 0x95, + 0xe9, 0x39, 0x2b, 0xa7, 0xd9, 0xa9, 0x73, 0x5a, 0xcf, 0x18, 0xf8, 0x94, + 0x56, 0x9f, 0x17, 0xec, 0xc7, 0x11, 0x16, 0x84, 0x19, 0x92, 0xa5, 0xfe, + 0x3e, 0xaa, 0x6f, 0x91, 0xa3, 0x3a, 0x27, 0x7b, 0x26, 0xe5, 0xe9, 0xb9, + 0xde, 0x94, 0x27, 0x88, 0xbb, 0x37, 0x7a, 0x77, 0x8e, 0x69, 0xe2, 0xc0, + 0x99, 0x74, 0xf4, 0xa7, 0x3f, 0xf1, 0x55, 0x54, 0x23, 0x82, 0xdd, 0xe4, + 0xbc, 0x84, 0xf9, 0xd3, 0x5b, 0xe8, 0xe9, 0xb0, 0xe9, 0xe1, 0x0f, 0xa2, + 0xe0, 0x30, 0x36, 0xa3, 0x2c, 0x29, 0x7f, 0x01, 0x79, 0x16, 0x4a, 0x49, + 0xa5, 0xf5, 0x62, 0x28, 0x09, 0x79, 0xd6, 0x29, 0x5d, 0x24, 0xbf, 0x19, + 0x1c, 0x65, 0xbd, 0xef, 0xaa, 0x88, 0xa9, 0x9b, 0xf2, 0x70, 0x1c, 0x14, + 0x6e, 0x96, 0xae, 0x78, 0x8e, 0x6d, 0xa4, 0x63, 0xf6, 0x5f, 0xfa, 0xc5, + 0xa1, 0x6d, 0x4e, 0xb6, 0xca, 0xd2, 0xed, 0xaa, 0xb0, 0x40, 0xbe, 0xa8, + 0x45, 0xe8, 0x16, 0xe5, 0xe4, 0xef, 0x5c, 0x12, 0xca, 0x05, 0xd7, 0x4d, + 0xfa, 0x89, 0xd3, 0x4f, 0x69, 0x9f, 0xae, 0xb6, 0xfe, 0x62, 0xae, 0xf6, + 0x09, 0x5d, 0x89, 0xea, 0x8c, 0xb6, 0xf9, 0xa0, 0x00, 0x67, 0xb5, 0x4f, + 0x00, 0x6a, 0x6c, 0xda, 0xc8, 0x7c, 0x41, 0xdb, 0xac, 0x41, 0xea, 0x99, + 0x23, 0x1b, 0x22, 0x26, 0xb4, 0x33, 0x7e, 0x7e, 0xb9, 0xae, 0x92, 0x6a, + 0x6a, 0x47, 0x2f, 0x37, 0x38, 0x8b, 0x24, 0xc7, 0x99, 0x6a, 0x27, 0x2f, + 0xdd, 0x8a, 0x94, 0xfe, 0xc6, 0xe5, 0x7d, 0xd5, 0xf9, 0xfb, 0x99, 0xd8, + 0xde, 0x41, 0xaa, 0x25, 0xfd, 0xe6, 0x72, 0xbe, 0x68, 0x0d, 0x15, 0x3b, + 0x9d, 0xf2, 0x9e, 0x6a, 0xc7, 0xc1, 0xec, 0x32, 0x1a, 0xf3, 0xb3, 0x41, + 0x75, 0x31, 0x2f, 0xf3, 0x62, 0xa4, 0xc6, 0xb1, 0x87, 0x52, 0xd2, 0xb6, + 0xcb, 0x06, 0x7b, 0x8d, 0xf7, 0x18, 0xe7, 0x9a, 0xfe, 0xcb, 0xe8, 0x6a, + 0xe7, 0x07, 0xd2, 0xde, 0xcb, 0x4f, 0x28, 0x25, 0x6c, 0x54, 0x4a, 0x68, + 0xc5, 0x12, 0x9a, 0xab, 0x49, 0x45, 0xfe, 0xfe, 0xfc, 0x30, 0x13, 0xa3, + 0x7b, 0x8d, 0x18, 0x39, 0x3f, 0x39, 0x4a, 0x8a, 0xb6, 0xdf, 0xb6, 0xe2, + 0xf2, 0xe3, 0x55, 0xaa, 0xd8, 0xc8, 0x08, 0x3d, 0x6f, 0xf3, 0xde, 0xcb, + 0x5a, 0xd1, 0x88, 0x36, 0x00, 0x9d, 0xf7, 0xa3, 0xd2, 0x5a, 0x23, 0xea, + 0xc3, 0x9a, 0xdd, 0xa6, 0x09, 0x70, 0xd6, 0x54, 0x90, 0xd2, 0x32, 0x18, + 0x7f, 0x78, 0x40, 0xa3, 0x9c, 0xe7, 0xae, 0x77, 0x8e, 0x41, 0x6b, 0x7c, + 0xa3, 0x4f, 0x3f, 0xfd, 0x98, 0x22, 0x33, 0x96, 0x04, 0x06, 0xe3, 0x7d, + 0xfd, 0x18, 0xd3, 0x92, 0x8e, 0xdc, 0x20, 0xa0, 0x9c, 0x91, 0x4f, 0x4f, + 0x00, 0x1f, 0x8c, 0xff, 0xae, 0x5f, 0x39, 0x3d, 0x5c, 0x4c, 0x77, 0x4e, + 0xa3, 0x33, 0x31, 0x74, 0x75, 0xfb, 0xe5, 0x82, 0xb3, 0x63, 0x9d, 0xfa, + 0x33, 0x6b, 0xaa, 0x7b, 0xe0, 0x28, 0x57, 0x0e, 0xba, 0x40, 0x75, 0xa0, + 0x02, 0x53, 0x76, 0xf7, 0x77, 0x46, 0x0b, 0x79, 0x0d, 0xad, 0x3d, 0x12, + 0x16, 0x1c, 0x3d, 0xe9, 0x05, 0x1a, 0x71, 0xd9, 0xdc, 0x8b, 0x96, 0x73, + 0xd0, 0x70, 0x4d, 0xaa, 0x77, 0xfa, 0x0d, 0x62, 0x8e, 0xf5, 0x22, 0x4c, + 0x30, 0x3b, 0x02, 0xf5, 0x81, 0x0b, 0x51, 0x83, 0x38, 0xd6, 0x6d, 0xec, + 0x31, 0x8a, 0x5a, 0x7a, 0x33, 0x90, 0x65, 0xb1, 0x8f, 0xc2, 0x33, 0x0d, + 0x92, 0x10, 0xed, 0xec, 0xdf, 0x85, 0xf4, 0x90, 0x63, 0x35, 0x88, 0x17, + 0x39, 0x98, 0xb0, 0xee, 0x6c, 0x3a, 0x6f, 0x47, 0x0d, 0x2c, 0x47, 0x30, + 0x48, 0xef, 0xc1, 0xbc, 0xea, 0x72, 0xac, 0xfd, 0x6a, 0xa9, 0x11, 0x05, + 0xca, 0x74, 0x7e, 0xb7, 0xb7, 0x46, 0x2a, 0x42, 0x8d, 0x69, 0xb7, 0xe0, + 0x38, 0x0b, 0xbc, 0x26, 0xac, 0x55, 0xc6, 0x9d, 0x83, 0x87, 0x22, 0x75, + 0x64, 0xc6, 0x6d, 0x59, 0xfe, 0x14, 0x91, 0x7e, 0x3d, 0x38, 0x76, 0x29, + 0x39, 0xea, 0x6f, 0x1c, 0xd2, 0x2b, 0xef, 0xa9, 0x43, 0x5a, 0xe5, 0x3d, + 0x79, 0x28, 0x45, 0x79, 0xbb, 0x86, 0x34, 0xca, 0x7b, 0xc2, 0x50, 0xe7, + 0x25, 0xe0, 0x29, 0x1e, 0xa6, 0xcc, 0x2d, 0xc8, 0xc0, 0x71, 0x37, 0x21, + 0xef, 0x0c, 0xdd, 0x25, 0x49, 0xeb, 0x2a, 0xf7, 0x95, 0x43, 0x82, 0xd3, + 0x89, 0x67, 0x61, 0x92, 0xef, 0x6e, 0x73, 0x71, 0xa0, 0x41, 0x81, 0xe3, + 0x5b, 0xfd, 0x45, 0xbe, 0x09, 0x35, 0x1a, 0x48, 0xf1, 0x84, 0x85, 0xdf, + 0x76, 0x3b, 0x6b, 0xc2, 0x42, 0xd6, 0x29, 0x52, 0x54, 0x8a, 0xfc, 0x01, + 0x78, 0x5d, 0x78, 0x5b, 0x2f, 0x71, 0x64, 0x0b, 0xac, 0x54, 0x1a, 0x58, + 0x81, 0xad, 0xf3, 0xf4, 0x13, 0x5e, 0x17, 0x59, 0x6a, 0x22, 0xe5, 0xba, + 0x66, 0xdd, 0x14, 0x29, 0x7a, 0x82, 0x17, 0xd9, 0xf7, 0xb9, 0x8f, 0xd0, + 0x02, 0xf8, 0x50, 0x5a, 0x2a, 0xa4, 0x23, 0xd0, 0x59, 0x9e, 0x6c, 0x6c, + 0xeb, 0x69, 0x18, 0xe3, 0x73, 0x5d, 0x83, 0x15, 0x8d, 0xd2, 0xd6, 0x82, + 0x8c, 0x93, 0x52, 0xfe, 0x84, 0xe2, 0x7f, 0x69, 0xa5, 0x3a, 0x02, 0x45, + 0xb4, 0x8d, 0x30, 0x1e, 0x9c, 0x3f, 0x92, 0xbf, 0x73, 0xa9, 0xab, 0x32, + 0xff, 0x56, 0x80, 0x03, 0x24, 0x39, 0x2e, 0xe8, 0x78, 0x78, 0x16, 0xdf, + 0x13, 0x54, 0x49, 0x1d, 0x30, 0xc8, 0x12, 0x53, 0x15, 0x4b, 0xc3, 0x8f, + 0x0c, 0x01, 0xec, 0x7d, 0x04, 0xa0, 0xe9, 0x11, 0x3a, 0xb7, 0x67, 0xe2, + 0x1d, 0x60, 0xf1, 0xe8, 0x9a, 0xe9, 0x69, 0xbf, 0x8b, 0xdd, 0xba, 0xb0, + 0x72, 0x12, 0x3c, 0xff, 0xbb, 0xb9, 0xc5, 0x53, 0xae, 0x85, 0xfe, 0x5c, + 0x1f, 0xe1, 0x97, 0x9a, 0x74, 0x53, 0x60, 0xc2, 0x15, 0xf9, 0x2a, 0x4e, + 0x74, 0x48, 0x1f, 0xe9, 0x28, 0x65, 0xbe, 0x8b, 0x52, 0x66, 0x1a, 0x50, + 0x39, 0xa3, 0x3b, 0x9b, 0x8f, 0x76, 0x54, 0xc1, 0x39, 0x28, 0x9a, 0x8c, + 0x6f, 0xf3, 0xb9, 0x33, 0xe3, 0x5f, 0x67, 0xe9, 0x8c, 0x58, 0x92, 0xb6, + 0x98, 0x7e, 0x28, 0xde, 0x23, 0xa7, 0x20, 0x4f, 0x82, 0xb0, 0x09, 0xf9, + 0x07, 0xc5, 0xf9, 0xe9, 0xc1, 0x94, 0x26, 0x4a, 0xf3, 0xf9, 0x48, 0x19, + 0xda, 0xd6, 0xd3, 0xe3, 0x90, 0xcf, 0x58, 0x2c, 0x1e, 0x83, 0x38, 0xa6, + 0xb9, 0xc7, 0x6b, 0x88, 0xf4, 0x8c, 0xb3, 0x78, 0x80, 0xb7, 0x34, 0x2b, + 0x6d, 0xc6, 0xf4, 0x8b, 0x02, 0x4c, 0x6c, 0xcc, 0xa0, 0x5e, 0xc9, 0x91, + 0x12, 0x4d, 0x11, 0x53, 0x5a, 0xad, 0x0d, 0xc6, 0xb2, 0x48, 0x4e, 0x33, + 0x18, 0x5d, 0xc6, 0xf0, 0x60, 0xdc, 0x3c, 0xec, 0x38, 0x44, 0xc2, 0x76, + 0x94, 0x38, 0x94, 0xff, 0xab, 0x5b, 0x32, 0x9f, 0xcc, 0x7a, 0x8a, 0x89, + 0x7d, 0x3e, 0x62, 0x53, 0x72, 0x7c, 0x7e, 0x99, 0xd8, 0x93, 0xfd, 0xae, + 0x55, 0xfc, 0x1f, 0x5d, 0xb6, 0x8b, 0x96, 0xc8, 0x98, 0xa7, 0x4f, 0x58, + 0xe8, 0x09, 0xc6, 0x96, 0xdd, 0x77, 0x9b, 0x75, 0xad, 0x8e, 0xc8, 0x12, + 0xcb, 0xf5, 0x76, 0x91, 0xdb, 0x6e, 0xf9, 0x41, 0x35, 0xb1, 0x3d, 0x5e, + 0x09, 0x76, 0x52, 0x61, 0xda, 0x99, 0xdd, 0x54, 0x7f, 0x8b, 0xf6, 0x74, + 0x6d, 0xe5, 0x51, 0xcb, 0x7c, 0x4b, 0x7e, 0x09, 0x9c, 0xfd, 0x55, 0xef, + 0x56, 0x4f, 0x76, 0xd3, 0x21, 0xce, 0x18, 0x7e, 0x0e, 0x69, 0xc2, 0x88, + 0x3c, 0xd6, 0x09, 0x4f, 0x20, 0xe7, 0xc8, 0x82, 0x36, 0xfc, 0xe5, 0x01, + 0xb5, 0xb3, 0xb3, 0xc6, 0xc8, 0x45, 0xcb, 0x31, 0x8b, 0xb1, 0xf9, 0x53, + 0xcb, 0x18, 0xc4, 0xd3, 0xb8, 0xb3, 0x16, 0x48, 0x52, 0xdd, 0xab, 0xa3, + 0xb5, 0x1f, 0xba, 0x8c, 0xda, 0x5a, 0x84, 0x86, 0x30, 0x43, 0xe9, 0x4a, + 0xc8, 0xbe, 0xcb, 0x49, 0x3a, 0xfd, 0x70, 0x20, 0x5d, 0xb4, 0x85, 0x8d, + 0x74, 0xf4, 0x9d, 0xdd, 0xd6, 0x4b, 0x47, 0xa1, 0xee, 0xac, 0x25, 0x92, + 0xa4, 0xdd, 0xdd, 0x43, 0xc9, 0xd6, 0x3f, 0x7e, 0x19, 0x26, 0xe8, 0x70, + 0x4c, 0x27, 0x43, 0x3f, 0x1d, 0x0d, 0xdd, 0x44, 0xbf, 0xa6, 0x9d, 0x2d, + 0x1d, 0xad, 0xe9, 0xfc, 0x68, 0x4d, 0x0f, 0x5e, 0xd6, 0x47, 0x92, 0x25, + 0xd7, 0x0d, 0x6b, 0x94, 0x90, 0x55, 0x97, 0xc1, 0xf1, 0x56, 0x40, 0xdb, + 0xfa, 0xa6, 0x3f, 0x1d, 0x39, 0xcc, 0x8d, 0xc3, 0x50, 0xfc, 0x9d, 0xd3, + 0xe9, 0xa2, 0x1b, 0x79, 0xdc, 0xf6, 0xde, 0x0a, 0x15, 0x48, 0x3f, 0xec, + 0xfd, 0x8b, 0x63, 0xb6, 0xef, 0x18, 0x5b, 0x81, 0x74, 0x0d, 0xdd, 0x8d, + 0x28, 0x91, 0x96, 0x34, 0x18, 0xc2, 0x74, 0x8f, 0xa9, 0x46, 0xb4, 0xa2, + 0x8b, 0x38, 0x1f, 0x3c, 0xab, 0x69, 0x25, 0x0e, 0x5a, 0xe6, 0x8b, 0x38, + 0x9a, 0x34, 0x4d, 0x4c, 0xcc, 0x8c, 0xa5, 0xac, 0x38, 0xab, 0x6b, 0xad, + 0x80, 0x69, 0x35, 0xd4, 0xc6, 0x0c, 0xf7, 0x66, 0xc0, 0x5f, 0x6c, 0xd3, + 0x3c, 0x5d, 0xec, 0x26, 0xc4, 0xc9, 0xe3, 0xbd, 0x67, 0x90, 0xde, 0x5b, + 0x05, 0x38, 0xb3, 0xef, 0xb2, 0x42, 0x61, 0x0e, 0x97, 0x6f, 0x20, 0xfe, + 0x4a, 0x42, 0xa1, 0x23, 0xac, 0x77, 0xe2, 0x65, 0x4a, 0xcf, 0x59, 0xfe, + 0x92, 0xcb, 0x3e, 0x3e, 0x62, 0x99, 0x53, 0x11, 0xf6, 0x98, 0x3d, 0xe9, + 0xd0, 0x7b, 0x99, 0xde, 0x7a, 0x11, 0xf1, 0x8c, 0xf5, 0xf4, 0x5c, 0x2e, + 0xac, 0x7e, 0xcf, 0x42, 0xa0, 0xd5, 0x63, 0xda, 0x39, 0x33, 0x6a, 0x1c, + 0x6d, 0xcf, 0xda, 0x21, 0xa5, 0x67, 0xa5, 0x95, 0x51, 0xf6, 0xb2, 0xf1, + 0x29, 0x28, 0x7e, 0x48, 0x4e, 0x8f, 0x54, 0xa8, 0xac, 0x29, 0x54, 0xda, + 0x59, 0x70, 0x34, 0x4e, 0x93, 0x89, 0x43, 0x27, 0xce, 0x17, 0xe8, 0x5a, + 0x31, 0x70, 0xa6, 0x48, 0x27, 0x0a, 0x32, 0x7d, 0x26, 0xa8, 0xf0, 0x5c, + 0x64, 0xdb, 0x04, 0xb6, 0x7b, 0xa5, 0xcb, 0x9a, 0xfa, 0x96, 0x25, 0xe2, + 0x31, 0xa1, 0x7d, 0x5c, 0x20, 0xa7, 0xfb, 0x8c, 0x11, 0x7a, 0xbf, 0x82, + 0x2f, 0x07, 0xe4, 0xb3, 0x97, 0x74, 0xe8, 0x83, 0x22, 0x8b, 0x27, 0x0b, + 0x50, 0x03, 0x53, 0x3d, 0xc3, 0x51, 0x5a, 0xdf, 0x27, 0x9f, 0xc6, 0x31, + 0x46, 0xc7, 0x16, 0x33, 0xa4, 0xec, 0x14, 0xd9, 0x08, 0x30, 0x6f, 0xda, + 0xf9, 0xc1, 0x84, 0x72, 0xf5, 0x08, 0x1d, 0x4b, 0x88, 0x41, 0xf9, 0x7b, + 0x51, 0x13, 0xa6, 0xcd, 0x45, 0x89, 0x69, 0x8a, 0x64, 0x09, 0xe7, 0xa5, + 0x74, 0x91, 0xb6, 0x57, 0x17, 0x41, 0x1a, 0x90, 0x12, 0xf1, 0x49, 0x83, + 0x94, 0xd7, 0x66, 0xb6, 0x64, 0xb5, 0x0e, 0xc4, 0x4d, 0x4a, 0xeb, 0x65, + 0xd4, 0x28, 0xb2, 0x3c, 0xad, 0x35, 0x0f, 0x0a, 0x22, 0xd7, 0x52, 0x43, + 0xa5, 0xc3, 0xbb, 0xd1, 0x6c, 0xd1, 0x2d, 0xbc, 0x83, 0x1a, 0x76, 0x22, + 0x3e, 0xf6, 0x9a, 0xf4, 0xff, 0x18, 0x51, 0xce, 0x6d, 0xc2, 0x3c, 0x03, + 0xf1, 0xbb, 0x50, 0x17, 0x7d, 0x59, 0x1a, 0xba, 0x44, 0x67, 0x85, 0x98, + 0xd8, 0xa5, 0xe1, 0x46, 0x1e, 0x1c, 0x3d, 0x6a, 0xaa, 0xd5, 0x27, 0xe3, + 0x1e, 0xc0, 0x7a, 0x93, 0x5a, 0xda, 0xa3, 0x73, 0xa0, 0xd0, 0x14, 0xce, + 0xd8, 0xb5, 0x79, 0xce, 0x96, 0x1a, 0xa3, 0x88, 0x3c, 0x26, 0x9c, 0x1d, + 0xd9, 0xe4, 0xa3, 0x77, 0x15, 0x1c, 0xee, 0x6d, 0xc4, 0x90, 0x5d, 0x95, + 0xf5, 0xb3, 0xf2, 0xc1, 0x14, 0xc9, 0x50, 0xe0, 0x34, 0x36, 0xa7, 0x22, + 0x45, 0x5c, 0x1a, 0xa2, 0xb5, 0x1a, 0x5b, 0x52, 0xb1, 0xd6, 0x8b, 0x23, + 0x74, 0x2c, 0x0d, 0xc4, 0x7f, 0x3d, 0xb2, 0xbe, 0xe6, 0x01, 0x9f, 0x06, + 0xe8, 0x6a, 0xd6, 0x7b, 0x4e, 0x65, 0x45, 0xd6, 0xd3, 0xd3, 0xb6, 0xe4, + 0x4c, 0x94, 0x4b, 0x20, 0xdf, 0x72, 0x89, 0x14, 0xad, 0x41, 0xae, 0x97, + 0xec, 0x95, 0xad, 0xfd, 0x49, 0xaa, 0x7c, 0xb4, 0x3f, 0x49, 0x87, 0x8d, + 0xfd, 0x49, 0xfe, 0xfa, 0x48, 0x7f, 0xce, 0x65, 0x98, 0x94, 0x23, 0x1b, + 0x45, 0xab, 0x2a, 0x5f, 0xa6, 0x67, 0xb5, 0x97, 0xc0, 0xdd, 0x48, 0x05, + 0x23, 0x68, 0xc5, 0xd2, 0x75, 0x21, 0x25, 0x48, 0x15, 0xdf, 0x41, 0xff, + 0xa1, 0x11, 0xaa, 0x41, 0x53, 0x4d, 0xec, 0x02, 0x97, 0xf3, 0x44, 0x6e, + 0x38, 0x27, 0x92, 0x2b, 0x9a, 0x9a, 0x33, 0xc2, 0x7b, 0xa2, 0x64, 0x92, + 0x4a, 0x56, 0xc6, 0x85, 0xbc, 0x11, 0x39, 0xf5, 0x9d, 0x73, 0x76, 0x46, + 0xd3, 0x9f, 0x9e, 0x3f, 0xe7, 0xef, 0xd1, 0x64, 0x59, 0xf3, 0x30, 0xef, + 0x8f, 0x46, 0xd2, 0x23, 0xf4, 0x66, 0x08, 0xb4, 0x4a, 0x4b, 0xb5, 0x72, + 0xa3, 0x23, 0x53, 0xb3, 0x83, 0x1b, 0xdb, 0x34, 0x2e, 0x3c, 0x36, 0x32, + 0x4e, 0x3c, 0x13, 0x65, 0x60, 0x6c, 0xf3, 0xb8, 0x70, 0xdf, 0x28, 0xef, + 0xa5, 0x7d, 0xfa, 0xbc, 0x7c, 0x93, 0x2f, 0x3b, 0x52, 0x81, 0x6d, 0xda, + 0x4b, 0xf7, 0x4f, 0x63, 0x3b, 0xa7, 0x25, 0x06, 0xe2, 0xce, 0x04, 0x6d, + 0x7f, 0xd2, 0x3f, 0x79, 0xa4, 0x42, 0x95, 0x1e, 0xb1, 0xa6, 0xb8, 0x51, + 0x23, 0xa3, 0xf8, 0x9d, 0x5a, 0x03, 0xce, 0x3b, 0xa5, 0xa9, 0x58, 0xd7, + 0xbe, 0x11, 0x4a, 0x7b, 0xd2, 0x45, 0x5a, 0xf7, 0x94, 0x1a, 0x4a, 0xcf, + 0x2f, 0xd2, 0x10, 0xf9, 0xe1, 0xe8, 0xef, 0x2e, 0xd2, 0xb2, 0x9d, 0xd2, + 0x09, 0x3e, 0x3b, 0xd2, 0xc3, 0x46, 0x84, 0xa2, 0x6e, 0x5a, 0xd6, 0xc4, + 0x9a, 0x89, 0x0a, 0x84, 0x50, 0x3c, 0x4e, 0x4a, 0x96, 0xfd, 0xb1, 0x92, + 0x9e, 0xb8, 0x06, 0xe2, 0x3f, 0xbd, 0x06, 0x6e, 0xc7, 0x28, 0xdc, 0x5c, + 0x93, 0x39, 0xcc, 0x45, 0xcc, 0x4a, 0xdb, 0xff, 0xe2, 0xc8, 0x10, 0x8f, + 0xb1, 0x22, 0x97, 0x8d, 0xf2, 0x36, 0x23, 0x4c, 0xe9, 0xc1, 0xb4, 0x27, + 0xe3, 0x19, 0x26, 0x66, 0x1a, 0xba, 0x2a, 0xbb, 0x07, 0xe2, 0xe9, 0x23, + 0x99, 0x91, 0x2c, 0x11, 0x7b, 0x8c, 0xde, 0x39, 0x06, 0x3f, 0xc1, 0xd6, + 0x72, 0xcd, 0xe6, 0xf0, 0xd9, 0x68, 0x06, 0xd6, 0x3a, 0x67, 0xe4, 0x17, + 0xca, 0x7a, 0xb3, 0x98, 0x42, 0xab, 0x54, 0xf7, 0x4f, 0xd2, 0x6f, 0xef, + 0x46, 0x2a, 0x0f, 0x12, 0x89, 0x67, 0x14, 0x59, 0x80, 0x7e, 0x1a, 0xfe, + 0xfa, 0x13, 0x53, 0xf6, 0xee, 0x4a, 0x24, 0x3e, 0x98, 0x31, 0xe5, 0xd2, + 0x8b, 0x53, 0xd0, 0xbe, 0xa5, 0x4b, 0xd4, 0x66, 0x26, 0x12, 0xef, 0xcf, + 0xa0, 0x6b, 0x96, 0x12, 0xf1, 0x8b, 0xca, 0xfa, 0xa8, 0xe7, 0x0c, 0xc9, + 0x73, 0x66, 0xc6, 0xa2, 0x36, 0xdf, 0x17, 0xcf, 0x1b, 0x42, 0x33, 0x44, + 0xb1, 0xfa, 0x4e, 0xf6, 0x07, 0x47, 0x2d, 0xc1, 0xbe, 0x78, 0xd6, 0x10, + 0x0d, 0xa3, 0x79, 0xfe, 0xd0, 0x1f, 0x1c, 0xcd, 0xd3, 0xd7, 0x41, 0x73, + 0xa4, 0x62, 0x2c, 0xfb, 0x75, 0x9e, 0x57, 0xfb, 0x95, 0x33, 0xd9, 0x95, + 0x96, 0x50, 0xbc, 0x98, 0x10, 0x2f, 0xa9, 0x52, 0x6e, 0x15, 0x4c, 0xd0, + 0x9c, 0x4e, 0xc4, 0xe7, 0xf4, 0x51, 0x5a, 0x78, 0x87, 0x2b, 0xce, 0x41, + 0x6b, 0x29, 0x7e, 0x4b, 0x9f, 0x3a, 0xa7, 0x3f, 0x4a, 0xcf, 0xdb, 0x19, + 0x88, 0xff, 0x64, 0x64, 0x36, 0x6c, 0xd4, 0xa9, 0x73, 0xb2, 0xaa, 0xa7, + 0xe6, 0xa8, 0x62, 0xdf, 0x42, 0x0e, 0xf4, 0x89, 0x6c, 0x52, 0xdc, 0x55, + 0xe8, 0xbe, 0x8c, 0xa3, 0x7f, 0x29, 0x2c, 0xd5, 0xd1, 0x32, 0x8d, 0xbe, + 0xf9, 0x02, 0xc5, 0x0c, 0xbd, 0xf7, 0x9d, 0x38, 0x68, 0x88, 0x56, 0x09, + 0xf9, 0x1d, 0x86, 0x1c, 0x93, 0xfa, 0xe2, 0xbf, 0x1d, 0x74, 0xa0, 0x75, + 0xfd, 0x27, 0xc4, 0x11, 0x95, 0x95, 0xa8, 0x46, 0x6e, 0xa4, 0xf8, 0xe8, + 0xeb, 0x48, 0x42, 0xfa, 0xa2, 0x62, 0xd1, 0xf2, 0xd8, 0x8e, 0x65, 0xff, + 0x06, 0xe9, 0xab, 0xc3, 0xdf, 0x40, 0x3a, 0x12, 0x8f, 0x27, 0xbe, 0x81, + 0x74, 0x84, 0x9e, 0xf3, 0xff, 0x35, 0xa4, 0xd3, 0x47, 0x21, 0xcd, 0x56, + 0xa0, 0x23, 0x0a, 0xa4, 0x19, 0x8a, 0xfb, 0xca, 0xd0, 0x7f, 0x82, 0xf4, + 0x27, 0xd7, 0x40, 0xaa, 0x53, 0x42, 0xd6, 0x8e, 0x42, 0xda, 0x30, 0x0a, + 0x29, 0xc5, 0xe5, 0xb5, 0xb0, 0xd2, 0x53, 0x91, 0xf2, 0x40, 0xdd, 0x44, + 0x76, 0xd2, 0x3d, 0x98, 0xb7, 0x48, 0x29, 0x50, 0x30, 0x49, 0xe8, 0x9e, + 0x51, 0xa3, 0xb3, 0xef, 0xaa, 0xb4, 0x80, 0xbf, 0x32, 0x3b, 0x84, 0x23, + 0xf5, 0xee, 0x5c, 0xd0, 0x42, 0xba, 0x47, 0x27, 0x7c, 0x29, 0x4f, 0x9c, + 0x30, 0x5d, 0x26, 0xe3, 0x73, 0x42, 0x4f, 0xe4, 0xc0, 0xa4, 0x7b, 0x25, + 0xd3, 0x24, 0xbd, 0xec, 0x9a, 0xa0, 0x95, 0x6d, 0xca, 0x79, 0x1d, 0x0b, + 0x9d, 0xdf, 0x96, 0x4d, 0x45, 0x2b, 0x43, 0xcc, 0x14, 0x97, 0xaf, 0x0c, + 0x06, 0x39, 0x0e, 0x54, 0xe1, 0x81, 0xf8, 0xca, 0x01, 0xe0, 0x89, 0xe3, + 0xd1, 0x4a, 0x0e, 0xd8, 0x9d, 0xf3, 0x05, 0x6c, 0xd7, 0x34, 0x7d, 0x49, + 0x6e, 0xb7, 0x11, 0x7e, 0x2a, 0xa0, 0x5e, 0xe2, 0x2c, 0xe8, 0xc9, 0x82, + 0x47, 0x6f, 0xd1, 0x1c, 0x67, 0x64, 0xb6, 0xf5, 0x59, 0x81, 0xe9, 0x21, + 0x7c, 0xd0, 0x6b, 0xe3, 0x26, 0x84, 0xe8, 0xd7, 0xb9, 0xe1, 0x78, 0xc9, + 0x10, 0x9d, 0xbd, 0x00, 0x1b, 0xfd, 0xbe, 0xee, 0x9c, 0xf0, 0x8e, 0x4c, + 0xeb, 0x7d, 0x13, 0x71, 0x33, 0x73, 0x9a, 0xb9, 0x84, 0x74, 0xdf, 0x70, + 0xe3, 0x19, 0x74, 0xd7, 0xa2, 0x5b, 0xd5, 0xfd, 0xed, 0x1b, 0xff, 0x12, + 0xcd, 0x82, 0xf3, 0x51, 0x70, 0xea, 0x4f, 0x53, 0x99, 0xa0, 0x6a, 0xc9, + 0xf2, 0xd3, 0x13, 0x36, 0xce, 0x49, 0x2b, 0xf2, 0x48, 0x58, 0xdb, 0x4b, + 0xd7, 0xa5, 0x7a, 0x04, 0x3a, 0xff, 0xda, 0x2d, 0xd1, 0xdd, 0xe5, 0x8c, + 0x48, 0xef, 0x9d, 0x3a, 0x16, 0x75, 0x15, 0xc0, 0xa4, 0x9f, 0xc9, 0xba, + 0xeb, 0x9f, 0x8f, 0xba, 0x26, 0x88, 0x92, 0xa1, 0xe8, 0x59, 0xec, 0xcb, + 0x12, 0x86, 0xda, 0x07, 0x89, 0x8d, 0x74, 0x5d, 0xd8, 0x9a, 0xd1, 0x19, + 0x8a, 0x24, 0xbd, 0xfe, 0x6e, 0xe0, 0x2a, 0xed, 0xd1, 0xf3, 0x12, 0xbe, + 0x09, 0xff, 0xcd, 0xd7, 0xe1, 0xdf, 0x56, 0xc2, 0xd5, 0x90, 0x46, 0xfb, + 0x7f, 0xe0, 0x9b, 0x19, 0xb1, 0xe1, 0x78, 0x8d, 0x42, 0xb7, 0x36, 0x78, + 0x16, 0xb5, 0x11, 0xdb, 0x48, 0xb0, 0xf3, 0xea, 0x9c, 0x0e, 0x9d, 0x8b, + 0xbb, 0x9a, 0x66, 0xea, 0x35, 0x69, 0xd2, 0x30, 0x8d, 0xab, 0x83, 0xee, + 0x55, 0xb4, 0xc0, 0xd3, 0x47, 0x60, 0x82, 0xfa, 0xf4, 0x8e, 0xd1, 0x99, + 0x9c, 0xdc, 0x23, 0xae, 0xce, 0xcd, 0x7c, 0xa0, 0x52, 0x84, 0x2d, 0x9b, + 0x80, 0x87, 0x9d, 0xec, 0xce, 0xdd, 0xc8, 0x97, 0xeb, 0xf3, 0x98, 0xb0, + 0x3a, 0x4c, 0xf8, 0x86, 0xca, 0x25, 0xc2, 0x7b, 0x9b, 0x8a, 0xc1, 0x26, + 0x32, 0xb1, 0x7b, 0x86, 0xbc, 0x39, 0x04, 0xf3, 0x39, 0xfd, 0x30, 0xe1, + 0x02, 0x72, 0x75, 0x88, 0x64, 0x05, 0x3f, 0x88, 0xc6, 0x15, 0xb8, 0xf3, + 0x15, 0xc8, 0xef, 0x56, 0x20, 0x87, 0xa7, 0x28, 0xec, 0xef, 0x26, 0x46, + 0x92, 0xf7, 0x68, 0x40, 0x06, 0xd6, 0x09, 0xbc, 0x7a, 0xae, 0xd3, 0xaf, + 0x8a, 0x7d, 0x67, 0xf0, 0x3f, 0xce, 0x61, 0x5d, 0x33, 0xcf, 0xa5, 0x8a, + 0xcd, 0xfb, 0x8f, 0x69, 0xe8, 0x9d, 0x42, 0x29, 0x0d, 0xe5, 0x0d, 0x3f, + 0x3c, 0x02, 0x36, 0xd5, 0xce, 0x88, 0x70, 0x6f, 0x0f, 0xa9, 0xd8, 0x0d, + 0x10, 0x4e, 0x81, 0x6c, 0xb7, 0x3a, 0x6c, 0x35, 0xb3, 0x61, 0x37, 0xba, + 0x98, 0x70, 0x8e, 0x99, 0x15, 0xc7, 0x07, 0xac, 0x81, 0xa9, 0x70, 0x77, + 0x4e, 0x09, 0x10, 0xa4, 0x99, 0xf9, 0xfd, 0xa4, 0xe9, 0x45, 0xa1, 0xe0, + 0x38, 0x14, 0x1e, 0xae, 0x64, 0x5a, 0xd4, 0xcf, 0xe8, 0xde, 0x27, 0x91, + 0xd6, 0xf6, 0xdb, 0xbd, 0x56, 0xe3, 0x02, 0x6f, 0xb5, 0xd9, 0x60, 0x14, + 0x39, 0x26, 0xb0, 0xad, 0xbd, 0xb9, 0xbd, 0x6e, 0xd6, 0x7c, 0x0b, 0x09, + 0xe4, 0x1a, 0xf5, 0x46, 0xb1, 0xfd, 0x3d, 0x4b, 0x46, 0xf6, 0x12, 0xce, + 0x9c, 0xdd, 0xdc, 0x6e, 0x65, 0x2d, 0x5e, 0x56, 0x7c, 0xbc, 0x92, 0xed, + 0x7a, 0x55, 0x38, 0x77, 0x8c, 0x47, 0xa8, 0x5c, 0x92, 0x0b, 0x54, 0xad, + 0xa8, 0xdb, 0xa0, 0x1d, 0x6d, 0xef, 0x71, 0x01, 0x14, 0x10, 0x51, 0xd5, + 0x4a, 0xdc, 0x24, 0x9c, 0xed, 0xca, 0x2e, 0x53, 0x05, 0x6c, 0x47, 0x23, + 0xed, 0xd9, 0xe6, 0x83, 0xed, 0xfb, 0x2c, 0x56, 0xe3, 0x44, 0x63, 0x76, + 0xf6, 0x12, 0xab, 0xd5, 0x9c, 0xa3, 0x94, 0x94, 0xe5, 0xd5, 0x75, 0xb1, + 0xe2, 0x0e, 0xe1, 0x13, 0x34, 0x39, 0x98, 0x88, 0x08, 0xc7, 0x95, 0xb9, + 0xb3, 0x31, 0x12, 0x69, 0xa1, 0x34, 0x49, 0xcb, 0xd6, 0xc8, 0xc9, 0x75, + 0x7c, 0x8c, 0xc8, 0xde, 0xd8, 0x26, 0x7c, 0x79, 0x1c, 0x44, 0x77, 0xed, + 0xef, 0xa3, 0x34, 0x15, 0xc6, 0x44, 0xc8, 0x74, 0x68, 0x66, 0x22, 0x6c, + 0x45, 0x64, 0x34, 0xe6, 0x7c, 0x34, 0xd6, 0xf1, 0xf4, 0x11, 0xa6, 0x99, + 0xae, 0x83, 0x57, 0xed, 0xd6, 0x85, 0xf5, 0xbb, 0x66, 0x2d, 0xd7, 0x42, + 0xe1, 0xd3, 0x30, 0x21, 0x4d, 0x36, 0xd9, 0x86, 0xe3, 0xc6, 0x21, 0x26, + 0x2f, 0x54, 0xc7, 0xca, 0x1f, 0xd9, 0xdf, 0xf5, 0xbd, 0x5b, 0x85, 0xe3, + 0xb7, 0x6f, 0x96, 0xff, 0x51, 0x3f, 0xeb, 0x7f, 0xdb, 0xff, 0xf0, 0x72, + 0x73, 0x80, 0xee, 0x96, 0x5e, 0x1c, 0x20, 0x7c, 0xd8, 0x53, 0xe3, 0xdf, + 0xe1, 0xa7, 0x27, 0x22, 0x7d, 0x3a, 0x0c, 0x8e, 0x87, 0x97, 0x5b, 0xfc, + 0x74, 0x3f, 0x80, 0xed, 0x34, 0xc1, 0x9e, 0x56, 0x89, 0x4b, 0x60, 0x89, + 0x4e, 0x1f, 0xd6, 0x3f, 0xfd, 0x6b, 0xdf, 0xaf, 0x6b, 0x9c, 0xa8, 0x8b, + 0x8d, 0x93, 0x7f, 0xe5, 0x2b, 0x88, 0x14, 0xab, 0x94, 0x11, 0x91, 0xc2, + 0x79, 0x89, 0x0c, 0xb1, 0xae, 0xe1, 0x97, 0xab, 0x8a, 0x44, 0xd4, 0xeb, + 0x9c, 0x8c, 0xd4, 0xee, 0x2b, 0x42, 0x1d, 0x4a, 0xd3, 0x92, 0xab, 0xdc, + 0xe2, 0xe4, 0xf4, 0x9f, 0xa3, 0x77, 0x7c, 0xed, 0xce, 0x0c, 0x67, 0xed, + 0xa2, 0x12, 0x83, 0x6a, 0x0f, 0x03, 0xf1, 0x19, 0x83, 0x6c, 0x9e, 0x5e, + 0x22, 0x7c, 0x01, 0xa6, 0xfc, 0x99, 0x4f, 0x13, 0x2e, 0xc2, 0xfa, 0x2e, + 0x49, 0x3f, 0xf5, 0x9d, 0x8b, 0x5a, 0x50, 0x77, 0xb6, 0x1e, 0xa2, 0xab, + 0x38, 0xa8, 0x1c, 0x61, 0x62, 0xdf, 0xea, 0x5f, 0x8d, 0xfc, 0xe4, 0xc1, + 0x54, 0x90, 0x1f, 0xe9, 0xa5, 0xf9, 0xb3, 0xc4, 0xa7, 0x6b, 0xac, 0xa8, + 0x5d, 0x59, 0xbc, 0x19, 0xb0, 0xdb, 0xc7, 0xed, 0xfa, 0x8a, 0x03, 0x87, + 0x88, 0xb2, 0xa5, 0x6d, 0x20, 0x52, 0x43, 0xdf, 0xef, 0x8f, 0xbe, 0x9f, + 0x1b, 0x60, 0x91, 0xe7, 0x51, 0x4d, 0x64, 0xc6, 0x60, 0x4b, 0x4d, 0x0b, + 0x86, 0xbc, 0x39, 0x70, 0xf5, 0xce, 0xa7, 0x81, 0xf8, 0x13, 0x03, 0x49, + 0x2d, 0xa5, 0x7a, 0x10, 0x1c, 0x4c, 0x13, 0x5d, 0x15, 0x44, 0x43, 0x87, + 0x06, 0xa0, 0x38, 0x45, 0x62, 0x5a, 0x06, 0xe2, 0x85, 0x83, 0x74, 0x8e, + 0x0a, 0x65, 0xe3, 0x00, 0xdd, 0xbb, 0xc7, 0x88, 0x56, 0x0b, 0x83, 0x63, + 0x61, 0x2c, 0x62, 0x79, 0xac, 0x33, 0xbd, 0x9b, 0xc2, 0x71, 0x1a, 0x1e, + 0xf5, 0x25, 0xad, 0xd8, 0x81, 0x78, 0x2f, 0xe6, 0xab, 0x96, 0xe8, 0xf7, + 0x27, 0x26, 0x0c, 0x98, 0xca, 0x22, 0xee, 0xb1, 0xd2, 0xf5, 0x0d, 0x6e, + 0x20, 0x15, 0xa9, 0x61, 0xf6, 0x24, 0xe1, 0x45, 0x2b, 0x6a, 0xae, 0x3c, + 0x6a, 0x35, 0xf4, 0x86, 0xb5, 0x1e, 0x26, 0x92, 0xaa, 0x68, 0x3c, 0xa9, + 0x18, 0x36, 0xa6, 0x39, 0x2d, 0xec, 0x10, 0x49, 0x81, 0xde, 0xb9, 0xb4, + 0x5b, 0xed, 0x64, 0xce, 0x42, 0x01, 0x5b, 0xe1, 0xc0, 0x90, 0x96, 0x3c, + 0x55, 0xf1, 0xd2, 0x6e, 0x55, 0x4c, 0x1a, 0x28, 0x99, 0x7a, 0xfd, 0x42, + 0x8b, 0x68, 0x8d, 0xec, 0xe1, 0x1a, 0x7c, 0x9f, 0x73, 0xb6, 0xd2, 0xf4, + 0xb3, 0x1e, 0x5e, 0xb4, 0x3c, 0xed, 0x59, 0xe6, 0x63, 0x5a, 0xae, 0x70, + 0xdd, 0x9e, 0x62, 0xef, 0x40, 0xfc, 0xe8, 0x00, 0xe1, 0xeb, 0xe7, 0x90, + 0x9b, 0xf5, 0x66, 0x2e, 0xfc, 0x60, 0xd4, 0xc6, 0x33, 0x2d, 0xa2, 0xa5, + 0xc5, 0xf3, 0x79, 0x74, 0x6c, 0xd3, 0xaf, 0xd0, 0xa6, 0x61, 0x14, 0xeb, + 0x7c, 0x81, 0x90, 0x46, 0xeb, 0x0b, 0xff, 0x3e, 0x4a, 0xe7, 0x86, 0x78, + 0xd1, 0x88, 0xf6, 0x0c, 0x38, 0xb3, 0xe8, 0xda, 0x02, 0xa0, 0x6e, 0xbe, + 0x39, 0xb5, 0x97, 0xf0, 0xff, 0xc4, 0x58, 0x3e, 0x92, 0x1e, 0xde, 0x55, + 0xc9, 0x88, 0xf5, 0xb3, 0x8c, 0x61, 0xe2, 0xa6, 0xa9, 0x00, 0x53, 0x81, + 0x23, 0xb4, 0x5c, 0xf0, 0xb3, 0xe5, 0x63, 0x20, 0x7b, 0xca, 0xcc, 0xc0, + 0xd3, 0x82, 0xf9, 0x14, 0xa5, 0x98, 0xa6, 0x21, 0xaa, 0xcd, 0x8f, 0x93, + 0x4f, 0xda, 0x19, 0x98, 0xe5, 0xab, 0x86, 0xf7, 0x2e, 0x13, 0xfe, 0x6f, + 0xb4, 0x86, 0x5d, 0x8e, 0x30, 0xa9, 0x50, 0xea, 0x70, 0x64, 0xb9, 0xa5, + 0x28, 0xc1, 0x3a, 0x99, 0x8a, 0xaf, 0xa2, 0xa4, 0x6c, 0xa6, 0x7f, 0x3e, + 0x9c, 0x89, 0x3e, 0xbc, 0x5c, 0x83, 0x1c, 0x53, 0x2b, 0xa6, 0x39, 0xe1, + 0xd4, 0x27, 0xbd, 0xf4, 0xd6, 0xe9, 0xbf, 0xf7, 0x52, 0xec, 0x34, 0xa0, + 0x8d, 0x92, 0x6e, 0x9f, 0xe8, 0x33, 0x78, 0xa8, 0x55, 0x9e, 0x1b, 0xb8, + 0x27, 0xc0, 0x88, 0x39, 0x19, 0x0c, 0x6f, 0x42, 0xdc, 0xf5, 0xa8, 0x53, + 0x4e, 0x4e, 0xf0, 0x19, 0x3d, 0x96, 0xe5, 0x4b, 0x96, 0x27, 0xb5, 0xd1, + 0xdf, 0xf4, 0xab, 0x78, 0x7a, 0x9b, 0x9d, 0x29, 0x5c, 0xe4, 0xcb, 0x0e, + 0xa3, 0x35, 0x22, 0xd3, 0x7b, 0xeb, 0x4a, 0xc1, 0x8d, 0x7d, 0x77, 0xb8, + 0x9f, 0xc6, 0xdc, 0x8d, 0x6d, 0xca, 0x11, 0x52, 0x24, 0x93, 0x58, 0x0c, + 0xc4, 0x6d, 0x0a, 0x67, 0x8b, 0x65, 0x90, 0xec, 0xb5, 0xdf, 0xf4, 0x53, + 0xbe, 0x9a, 0x2d, 0xa2, 0x45, 0xe9, 0xee, 0x45, 0x3e, 0x7d, 0x3d, 0xda, + 0xa8, 0x73, 0x55, 0x49, 0x9b, 0x35, 0x7d, 0x3c, 0x40, 0x39, 0xba, 0xa7, + 0xa8, 0x92, 0xeb, 0x4c, 0x5e, 0x48, 0xda, 0xb2, 0x33, 0x88, 0xa2, 0x73, + 0xf7, 0xcd, 0xa8, 0xf5, 0xae, 0xa9, 0xff, 0xd9, 0x0f, 0x8f, 0xcd, 0x78, + 0xe9, 0x5d, 0xff, 0x8e, 0xe2, 0xed, 0xbf, 0x9b, 0x31, 0xb8, 0xe1, 0x99, + 0x79, 0x59, 0xb3, 0x8e, 0xcf, 0xa0, 0xf6, 0x2d, 0x3d, 0x5f, 0x34, 0x53, + 0x99, 0x0b, 0x32, 0x8d, 0x3c, 0xa2, 0x4a, 0xda, 0xbb, 0x49, 0xf8, 0xc1, + 0x39, 0x56, 0xa2, 0x70, 0xdf, 0x25, 0xa4, 0xf3, 0xaf, 0xd4, 0xf0, 0x9e, + 0x1e, 0x65, 0xfc, 0x53, 0x58, 0xee, 0xef, 0x27, 0x45, 0xa0, 0xb4, 0xe4, + 0x17, 0x68, 0xf5, 0x23, 0x36, 0xa4, 0x5d, 0xbd, 0xe0, 0xdc, 0x23, 0x8f, + 0x55, 0xf4, 0x4c, 0xb1, 0x57, 0xb7, 0x5b, 0xff, 0x74, 0x52, 0xbf, 0x3c, + 0x88, 0x94, 0xbc, 0xbf, 0x9f, 0x6a, 0x6c, 0x4d, 0xbd, 0x5a, 0x25, 0xf6, + 0xf1, 0x5e, 0xaa, 0x8d, 0x56, 0x9e, 0xc5, 0xf2, 0x95, 0x14, 0xf7, 0xe4, + 0xed, 0xc3, 0x34, 0xbe, 0x7e, 0x93, 0x48, 0xcb, 0xa3, 0x6d, 0x46, 0x2b, + 0xa0, 0x85, 0x96, 0x90, 0x8d, 0xbc, 0xf0, 0x57, 0xfd, 0xf4, 0xbb, 0xcd, + 0x40, 0xbc, 0xa2, 0x1f, 0x1c, 0xad, 0x98, 0xce, 0xd4, 0x6f, 0x6a, 0xca, + 0xd8, 0x49, 0x35, 0x6f, 0x5d, 0xb3, 0x3e, 0xfc, 0x44, 0x4d, 0x86, 0x42, + 0x99, 0xe3, 0xd0, 0xb6, 0xcf, 0xc6, 0x52, 0x6b, 0x47, 0x35, 0xe4, 0x26, + 0x4c, 0xf9, 0x79, 0x9f, 0x0e, 0xf5, 0xd7, 0xe4, 0xb8, 0xf9, 0x1e, 0x85, + 0x40, 0x7a, 0xf1, 0xfc, 0x8e, 0xaa, 0x8c, 0xd6, 0x47, 0x2b, 0x6b, 0x67, + 0x25, 0xc7, 0x95, 0x2e, 0x32, 0x10, 0x5f, 0xac, 0xc4, 0x3c, 0x73, 0x3e, + 0x53, 0xcc, 0x52, 0xf8, 0x11, 0x9d, 0x09, 0x85, 0xd3, 0xeb, 0xce, 0x31, + 0x91, 0xb4, 0x52, 0x38, 0xbb, 0xfa, 0x5c, 0x48, 0x99, 0x6d, 0xb9, 0x0b, + 0xf9, 0xb3, 0x21, 0x9c, 0xb2, 0x8b, 0xa7, 0xb1, 0x3d, 0xf1, 0x64, 0x4b, + 0xce, 0x5e, 0xe9, 0x05, 0x69, 0xf3, 0x79, 0x43, 0x4b, 0x0a, 0x72, 0x89, + 0xfb, 0xb1, 0xc6, 0xbf, 0xf7, 0xd1, 0xbb, 0x00, 0x07, 0xe2, 0x37, 0xf7, + 0x6b, 0xf7, 0xa0, 0x0a, 0x88, 0xe5, 0x2e, 0x3a, 0xaf, 0x11, 0x35, 0x11, + 0xe2, 0xd6, 0x85, 0xcb, 0xf8, 0xac, 0x60, 0x72, 0x25, 0xec, 0x1d, 0xe7, + 0x27, 0x0b, 0x5a, 0xec, 0x5f, 0xda, 0x52, 0x3a, 0x4f, 0x30, 0x10, 0xff, + 0x53, 0x9f, 0x1b, 0xe8, 0x3c, 0xc1, 0xe2, 0x28, 0xb3, 0x47, 0x2b, 0x36, + 0xa2, 0x25, 0x93, 0xde, 0xba, 0x38, 0x6f, 0x91, 0xef, 0xea, 0xbc, 0x13, + 0x94, 0xdc, 0x2e, 0x81, 0xed, 0xee, 0xea, 0x81, 0x78, 0x64, 0xb4, 0x86, + 0x47, 0xfb, 0x34, 0x11, 0x0d, 0xb6, 0x7c, 0x1c, 0xb6, 0x9a, 0xe2, 0xa3, + 0x7e, 0x96, 0x39, 0x4c, 0x77, 0xb8, 0x0e, 0xc4, 0xa7, 0xf6, 0x67, 0x37, + 0x0d, 0xc4, 0x73, 0xfb, 0xbf, 0xe1, 0x1d, 0xab, 0xfb, 0xc6, 0x89, 0xe3, + 0x14, 0x18, 0xb2, 0x11, 0x1b, 0x2e, 0x77, 0x56, 0x90, 0x62, 0x8f, 0x62, + 0xe5, 0x0c, 0xca, 0x83, 0x07, 0x64, 0x65, 0x7d, 0x85, 0xcd, 0x83, 0xa5, + 0x2f, 0xea, 0xa3, 0x31, 0x03, 0x71, 0xa9, 0x8f, 0xc2, 0x7e, 0xac, 0xd7, + 0x2c, 0xea, 0x22, 0x68, 0xcb, 0xca, 0xc1, 0xa8, 0xa9, 0x25, 0x03, 0xdb, + 0x48, 0xf5, 0xf7, 0x87, 0xfa, 0xae, 0xf7, 0xd1, 0x1a, 0x93, 0x78, 0x1e, + 0x88, 0xaf, 0xe9, 0xd3, 0x29, 0x38, 0x1e, 0x17, 0xfe, 0x6d, 0x94, 0xd2, + 0xf2, 0x40, 0x7c, 0xd9, 0x28, 0x6c, 0xba, 0xff, 0x01, 0xdb, 0x47, 0x7d, + 0xe3, 0x10, 0xb6, 0xf7, 0xfb, 0xbe, 0x81, 0xcd, 0x86, 0xb0, 0xe9, 0x22, + 0x14, 0xa6, 0x2c, 0x30, 0x23, 0x8c, 0xb4, 0x24, 0x5d, 0x38, 0x2c, 0x4c, + 0x90, 0x69, 0x8d, 0x9a, 0x48, 0xb6, 0xd2, 0xbb, 0xe0, 0xd0, 0x85, 0xf3, + 0xb0, 0xee, 0xcc, 0x6b, 0x72, 0xee, 0x52, 0x60, 0x6c, 0xec, 0xa5, 0x10, + 0x83, 0x6d, 0x6c, 0x75, 0x7f, 0x7c, 0x20, 0xf1, 0x4d, 0xec, 0x1a, 0x1a, + 0x2b, 0x67, 0x23, 0x27, 0xb7, 0x00, 0x99, 0xae, 0x6b, 0xce, 0x0c, 0xb9, + 0x4a, 0xfb, 0x24, 0x5d, 0x98, 0x79, 0xf2, 0xce, 0x5e, 0x70, 0x68, 0xb0, + 0xac, 0xac, 0x3e, 0x5a, 0x57, 0x3b, 0x8e, 0xa3, 0x6f, 0xe6, 0x78, 0xa8, + 0x7e, 0x5f, 0xe0, 0x01, 0xc8, 0xc1, 0xa7, 0x6b, 0x08, 0x20, 0x9b, 0xbe, + 0x1f, 0xa1, 0xfa, 0xbd, 0x56, 0xd4, 0xec, 0x21, 0x15, 0xa2, 0xd9, 0x18, + 0xa6, 0x74, 0x69, 0x88, 0xa4, 0x88, 0xb4, 0x9e, 0xfe, 0xf8, 0x31, 0xb4, + 0x7b, 0x36, 0xf6, 0x69, 0xb1, 0x55, 0x4b, 0xfb, 0x68, 0x68, 0x7f, 0x3c, + 0xfa, 0x35, 0x14, 0xfd, 0xf1, 0x5f, 0x24, 0xdc, 0xa0, 0x8d, 0x90, 0xeb, + 0x5d, 0xe5, 0x96, 0xa0, 0x31, 0xa2, 0x7b, 0x32, 0x82, 0xb6, 0x35, 0x8d, + 0xed, 0x8f, 0xbf, 0x90, 0xa0, 0xa9, 0x93, 0xb4, 0x79, 0x1d, 0xc2, 0x6a, + 0x95, 0xaf, 0x96, 0x39, 0x10, 0xd7, 0xa3, 0x9f, 0x91, 0xb4, 0x62, 0x8f, + 0xd6, 0x74, 0x62, 0x2a, 0xa8, 0x5b, 0x49, 0xec, 0xbb, 0xa8, 0x43, 0xea, + 0x22, 0x4c, 0x4b, 0x56, 0xb0, 0x40, 0x24, 0x2e, 0xce, 0x5f, 0xa4, 0x8c, + 0xa3, 0xe7, 0x2f, 0x5a, 0xfc, 0x6d, 0x17, 0x99, 0x3d, 0x3a, 0x3a, 0xdb, + 0x5d, 0x61, 0x09, 0x4d, 0x43, 0x89, 0xab, 0x41, 0x6b, 0x3c, 0x2e, 0xbb, + 0x1c, 0x9a, 0x56, 0x72, 0xbd, 0x21, 0x68, 0x09, 0x11, 0xac, 0xf9, 0x51, + 0xb4, 0xf4, 0x0e, 0xfa, 0xfa, 0xe3, 0x91, 0x04, 0x95, 0x65, 0xb4, 0xce, + 0xfe, 0xf8, 0x5f, 0xd1, 0xda, 0x15, 0xa5, 0xf7, 0xd1, 0x12, 0x4c, 0xdb, + 0x63, 0xd8, 0x0d, 0x13, 0x33, 0x25, 0x47, 0x84, 0x94, 0x2e, 0x3b, 0xc3, + 0xa1, 0x86, 0x78, 0xb7, 0xb4, 0xb7, 0x46, 0xe4, 0x0c, 0x11, 0x62, 0x3f, + 0xc6, 0x19, 0x9a, 0x53, 0x23, 0x53, 0x71, 0xd4, 0xa7, 0x86, 0x49, 0xcc, + 0x3d, 0x48, 0xbf, 0xd6, 0xa5, 0x9d, 0x4d, 0xc5, 0xda, 0x53, 0xce, 0xa6, + 0x46, 0x78, 0xd8, 0xa5, 0xcc, 0xde, 0x18, 0x94, 0x39, 0x1b, 0x9a, 0xf2, + 0xb8, 0x25, 0x35, 0x4c, 0xbf, 0x41, 0xe4, 0x2b, 0x76, 0xf4, 0x1d, 0x12, + 0x4c, 0xca, 0x38, 0x5b, 0x02, 0xe5, 0xf4, 0xd4, 0xb7, 0xd8, 0xe9, 0x41, + 0x75, 0x84, 0xa0, 0x36, 0x47, 0xdd, 0x05, 0x83, 0xea, 0xd6, 0xec, 0x26, + 0xea, 0x4a, 0x1d, 0xc8, 0x16, 0xd5, 0x98, 0x27, 0x62, 0x7d, 0x49, 0xa0, + 0xab, 0x88, 0x69, 0x6b, 0xdf, 0x19, 0x44, 0x7d, 0xdc, 0x4e, 0x63, 0x07, + 0x06, 0xc6, 0x88, 0x1a, 0x00, 0x67, 0x19, 0xf2, 0x58, 0xa2, 0xe4, 0xfc, + 0xe5, 0xa0, 0x03, 0x43, 0x88, 0x73, 0xe2, 0x59, 0xfa, 0xd5, 0xc2, 0xdd, + 0xa0, 0x72, 0x8b, 0x70, 0x85, 0x5b, 0x18, 0x20, 0xb1, 0xdd, 0x03, 0x36, + 0x9e, 0xb3, 0x4c, 0xeb, 0xbd, 0x9e, 0xb7, 0x44, 0x68, 0x9b, 0x50, 0xe2, + 0x44, 0xb5, 0xe2, 0x3d, 0x79, 0x69, 0xe2, 0x4b, 0x82, 0xb6, 0x67, 0x8f, + 0x55, 0x2b, 0x62, 0x3b, 0x9d, 0xe1, 0xd3, 0x17, 0x2d, 0xc0, 0x37, 0x45, + 0xd3, 0xc4, 0x31, 0x91, 0x2b, 0x96, 0xe3, 0x5c, 0xda, 0x93, 0x63, 0xc2, + 0x50, 0x14, 0x8b, 0xa6, 0x45, 0xba, 0xa2, 0xb4, 0x44, 0x94, 0x6c, 0x28, + 0x61, 0xa8, 0x8b, 0xda, 0xa2, 0x69, 0xb2, 0x1e, 0xad, 0xee, 0x14, 0xf9, + 0x6e, 0x9f, 0x3e, 0x92, 0x85, 0x63, 0x96, 0xae, 0xee, 0x33, 0x84, 0x53, + 0xf1, 0x17, 0xf1, 0x81, 0x69, 0xc6, 0x88, 0xf4, 0xab, 0xdf, 0xab, 0x72, + 0xaa, 0x98, 0xef, 0xe0, 0x38, 0x15, 0x64, 0x79, 0x4c, 0x42, 0xa5, 0x44, + 0xca, 0x8f, 0x59, 0xd8, 0xd2, 0x19, 0x67, 0x73, 0x1c, 0xc7, 0x2d, 0x88, + 0x1b, 0x2e, 0x89, 0x45, 0x8a, 0x43, 0x3a, 0x2b, 0xa5, 0xc6, 0xb6, 0x24, + 0xdb, 0xf9, 0x02, 0xb6, 0x33, 0x55, 0x09, 0x41, 0x0e, 0xaf, 0xb4, 0xee, + 0xb9, 0x41, 0x0d, 0x50, 0x0e, 0x5a, 0x24, 0x95, 0x81, 0xba, 0x85, 0xc4, + 0x0c, 0x68, 0xe5, 0xd8, 0x4e, 0x33, 0xa2, 0xc1, 0x41, 0x25, 0xf5, 0x54, + 0xaa, 0x93, 0x62, 0xbe, 0xa7, 0xfa, 0xd3, 0x45, 0x75, 0x13, 0xa5, 0x80, + 0x65, 0xe7, 0x94, 0x75, 0xae, 0x0e, 0x9a, 0xf7, 0xf1, 0x7e, 0xa3, 0x88, + 0xfd, 0xe3, 0x9c, 0x7d, 0xc6, 0x21, 0x32, 0xce, 0xd4, 0x33, 0xde, 0x5e, + 0xb6, 0xf4, 0x77, 0x52, 0x16, 0xe4, 0xb8, 0x5f, 0x8b, 0x52, 0x6e, 0x35, + 0x45, 0x09, 0x2f, 0x3f, 0xab, 0x45, 0x39, 0x4a, 0xf9, 0xaf, 0x51, 0xc6, + 0x3a, 0x94, 0x9c, 0x6b, 0xd0, 0x3a, 0x23, 0x4a, 0x7d, 0xc7, 0xe8, 0x4c, + 0xfa, 0xd9, 0xe7, 0x2f, 0xf1, 0x62, 0x8f, 0x97, 0x09, 0x6b, 0x90, 0xae, + 0xa0, 0x40, 0x39, 0xb3, 0x2f, 0x36, 0xad, 0x1f, 0x26, 0x82, 0xfc, 0xcb, + 0xcb, 0xa8, 0x87, 0x4b, 0x87, 0x85, 0xe4, 0x7e, 0x73, 0x12, 0x9b, 0xd4, + 0x5f, 0xa2, 0xbc, 0x4b, 0xfb, 0x0f, 0x5e, 0x86, 0xa2, 0x29, 0x68, 0x7f, + 0x30, 0x4f, 0x66, 0x23, 0xe7, 0x7b, 0xf4, 0x52, 0xba, 0x42, 0xa1, 0x7f, + 0xee, 0xa5, 0xb5, 0x61, 0x1e, 0xa4, 0x02, 0x87, 0x92, 0x92, 0xd2, 0x50, + 0x1a, 0x4a, 0x36, 0xba, 0xbf, 0x65, 0x2a, 0x34, 0x60, 0xbf, 0xbd, 0xdb, + 0xc7, 0xe6, 0xa5, 0xe3, 0xa8, 0x50, 0xfb, 0xd4, 0xd5, 0x89, 0xb8, 0x7a, + 0x90, 0xda, 0xdb, 0x05, 0x9e, 0xab, 0xdf, 0x26, 0xa8, 0x3c, 0xfa, 0x88, + 0x01, 0x1c, 0x17, 0xce, 0xaf, 0xe7, 0x2c, 0x07, 0xe8, 0x1e, 0x74, 0x47, + 0x12, 0x82, 0x94, 0x41, 0x8d, 0x68, 0x8c, 0x18, 0x90, 0xfe, 0x45, 0x8e, + 0x38, 0x26, 0x20, 0x7d, 0x65, 0x63, 0xcf, 0x65, 0x79, 0xd2, 0xc3, 0x14, + 0x83, 0x89, 0xf8, 0x4d, 0x03, 0x2a, 0x7a, 0x3b, 0xa0, 0x3b, 0xb5, 0x49, + 0xdd, 0xa2, 0x45, 0x1a, 0xae, 0x45, 0x9b, 0x34, 0xad, 0x29, 0xd9, 0xa6, + 0x07, 0x07, 0xdf, 0x0a, 0xe8, 0x9a, 0x4c, 0xd8, 0x93, 0xc6, 0x30, 0x9d, + 0x7d, 0x62, 0xe5, 0x24, 0x16, 0x6e, 0x1b, 0x34, 0x36, 0xd1, 0xf5, 0x83, + 0x24, 0xf6, 0xdb, 0x3e, 0x03, 0x96, 0x4e, 0x39, 0xa7, 0x43, 0xcc, 0xf2, + 0xa6, 0x47, 0xb2, 0xbc, 0x46, 0x59, 0x2b, 0x4e, 0xc3, 0xfe, 0xa1, 0x54, + 0xce, 0xe0, 0x48, 0x28, 0x43, 0x6d, 0xc3, 0x20, 0x6a, 0x23, 0x96, 0xe0, + 0xf2, 0x28, 0x0d, 0x63, 0x7b, 0x1c, 0x91, 0x64, 0xca, 0x7c, 0x65, 0xce, + 0x25, 0x76, 0x16, 0x7b, 0x4c, 0xc1, 0xf2, 0x2b, 0x03, 0x65, 0xd4, 0xce, + 0x8c, 0xd9, 0x10, 0xc7, 0xaa, 0x33, 0x17, 0x65, 0x3a, 0xbe, 0xcf, 0x9d, + 0xa4, 0xa5, 0xf5, 0xc8, 0xd3, 0x78, 0x03, 0x5a, 0x26, 0xdf, 0x8c, 0xe3, + 0x00, 0xd2, 0xd0, 0xc9, 0x28, 0xcd, 0xaf, 0x3d, 0x4b, 0x53, 0x7c, 0x86, + 0xdc, 0x00, 0xc7, 0x23, 0x72, 0xc9, 0x1b, 0xa2, 0xc9, 0xda, 0xb2, 0x45, + 0xfa, 0xfd, 0xe0, 0x66, 0xb4, 0x69, 0x0c, 0x0e, 0x75, 0xab, 0xd2, 0xff, + 0x7d, 0x48, 0x1d, 0x4d, 0x06, 0x05, 0x2f, 0x87, 0x05, 0x8d, 0x4c, 0x62, + 0x5b, 0x90, 0xc3, 0xa9, 0x41, 0x27, 0x1a, 0xc2, 0xa1, 0x28, 0x89, 0x3d, + 0xd2, 0x47, 0x6f, 0x0c, 0xa4, 0xe9, 0x69, 0xea, 0x07, 0xfa, 0xd4, 0xf0, + 0xcf, 0xa8, 0xd2, 0x3b, 0x05, 0x49, 0x4c, 0xed, 0xef, 0xd7, 0x88, 0x2e, + 0x17, 0x77, 0xa7, 0x51, 0x24, 0x93, 0xb5, 0x4d, 0x6d, 0x82, 0xf6, 0x6c, + 0x32, 0x2d, 0xa5, 0xb8, 0x7b, 0xfa, 0xd4, 0x4d, 0x1f, 0x23, 0x3c, 0x94, + 0xda, 0xe1, 0x2c, 0x87, 0x1d, 0xa4, 0x11, 0xad, 0x9c, 0x2e, 0x7c, 0xb5, + 0x6d, 0x55, 0xa3, 0x6d, 0x6b, 0x47, 0xbd, 0x52, 0x3c, 0xc3, 0x28, 0x6d, + 0x7b, 0xea, 0xc4, 0xd5, 0xf6, 0xb8, 0x4a, 0x07, 0xa4, 0x9e, 0xcb, 0x94, + 0x33, 0xfd, 0x58, 0x4e, 0x4a, 0xc0, 0x32, 0xbe, 0x35, 0xaa, 0x47, 0xad, + 0x5b, 0x13, 0xd6, 0xd1, 0x5b, 0xaf, 0xa4, 0x44, 0xfc, 0xe6, 0x01, 0xfa, + 0xd0, 0x16, 0xbf, 0xa2, 0xd0, 0x29, 0x9c, 0x3d, 0x7c, 0x99, 0xce, 0xbd, + 0x94, 0x60, 0xff, 0x97, 0xa9, 0x92, 0xe7, 0x60, 0x1b, 0xf3, 0x18, 0x19, + 0x8a, 0xe8, 0x39, 0x70, 0xdf, 0xd8, 0x8c, 0x43, 0xf1, 0xbc, 0xe1, 0x32, + 0xdf, 0x6e, 0xc1, 0xfc, 0x1f, 0xd6, 0x43, 0x30, 0xb1, 0x0d, 0x43, 0x46, + 0x47, 0xdb, 0x3d, 0xe0, 0xcc, 0x96, 0xf7, 0xad, 0x26, 0xee, 0xb1, 0x90, + 0xe7, 0xb1, 0x08, 0x67, 0xe5, 0x64, 0xdc, 0x9a, 0xa1, 0x53, 0xd1, 0x82, + 0xd1, 0x75, 0x0e, 0xe7, 0xa2, 0x0e, 0x74, 0xfd, 0x4d, 0xfe, 0x24, 0x40, + 0x2d, 0x6a, 0x7a, 0x72, 0xdf, 0xec, 0x3e, 0x7e, 0x05, 0xe5, 0x3c, 0x1a, + 0x3a, 0xe7, 0xb4, 0x9c, 0xae, 0xe4, 0x21, 0xa7, 0x49, 0xd1, 0x83, 0x42, + 0xdb, 0x36, 0xab, 0x46, 0x75, 0x12, 0xc3, 0x1a, 0x20, 0xb6, 0xb6, 0xbf, + 0x76, 0x05, 0x94, 0xe8, 0x24, 0x1e, 0x66, 0xb9, 0xff, 0x7f, 0xdd, 0x7d, + 0x0b, 0x7c, 0x54, 0xe5, 0xb5, 0xef, 0xfa, 0xf6, 0xde, 0xf3, 0xca, 0xc3, + 0x0c, 0x24, 0xc0, 0x9e, 0x99, 0x10, 0xf6, 0xcc, 0x26, 0x21, 0x0f, 0x1e, + 0x13, 0x26, 0x68, 0x20, 0xa8, 0xc3, 0x1e, 0x08, 0x09, 0x51, 0xa4, 0xa8, + 0x3d, 0x68, 0x44, 0xf7, 0x90, 0x04, 0xf7, 0xf0, 0x08, 0x91, 0x97, 0xa1, + 0xed, 0x3d, 0x04, 0xd1, 0x96, 0x88, 0xb6, 0x81, 0x81, 0x63, 0x92, 0x21, + 0x94, 0x92, 0xe2, 0x8b, 0x63, 0x4b, 0xb1, 0x69, 0x3d, 0x62, 0x4a, 0x2c, + 0xad, 0x4a, 0xb5, 0x76, 0x46, 0xc0, 0x06, 0x42, 0x4e, 0xe3, 0x73, 0xab, + 0x94, 0x1a, 0x2b, 0x32, 0x21, 0xaf, 0xb9, 0xeb, 0xdb, 0xb3, 0x81, 0x80, + 0x9e, 0xd3, 0x73, 0xef, 0xef, 0x9e, 0xdf, 0xfd, 0xdd, 0x3b, 0xbf, 0xdf, + 0x7f, 0xf6, 0xfb, 0x7b, 0xaf, 0x6f, 0xad, 0xf5, 0x3d, 0xd6, 0x6a, 0x92, + 0x18, 0xcd, 0xe2, 0xdf, 0x83, 0x97, 0x40, 0xac, 0xa8, 0xf8, 0xc9, 0x2a, + 0xba, 0x27, 0x48, 0xb3, 0x00, 0x48, 0xed, 0x1a, 0x56, 0x0e, 0x46, 0x0f, + 0x0e, 0x82, 0x98, 0x09, 0xad, 0x5b, 0x5a, 0xab, 0x97, 0xcc, 0xe8, 0x32, + 0x31, 0x27, 0xa9, 0xbf, 0xbc, 0xa9, 0x83, 0xf4, 0x3f, 0x6b, 0x70, 0x30, + 0xfa, 0xd3, 0xc1, 0x20, 0xe6, 0x95, 0xae, 0xad, 0x18, 0xb9, 0xae, 0x22, + 0x1a, 0xbd, 0x41, 0x9b, 0xf5, 0xdf, 0xa2, 0xd9, 0x64, 0x49, 0x12, 0xff, + 0x70, 0x3f, 0xf5, 0x7f, 0xbd, 0xe3, 0x70, 0xaa, 0xe9, 0xc1, 0x93, 0x75, + 0xa2, 0x83, 0xa4, 0xfa, 0x96, 0x29, 0xad, 0x5b, 0x20, 0x97, 0x3b, 0xeb, + 0x5a, 0x45, 0xad, 0xf6, 0x53, 0xbb, 0x7d, 0xea, 0x0a, 0x98, 0xd6, 0x1f, + 0x06, 0x57, 0x9d, 0x73, 0xaa, 0x92, 0x2b, 0xdb, 0xa1, 0x94, 0x24, 0x78, + 0x13, 0xa5, 0xc2, 0xb0, 0xbc, 0xba, 0xb5, 0xbe, 0xdc, 0x64, 0x3c, 0x55, + 0xa1, 0x74, 0xd8, 0x2b, 0x56, 0xd2, 0xb9, 0x08, 0x71, 0x55, 0x87, 0x9d, + 0xc1, 0xbc, 0x51, 0x6b, 0x90, 0xea, 0x8a, 0x97, 0xe6, 0xff, 0xa4, 0xde, + 0x97, 0x6e, 0x44, 0x1d, 0x76, 0x7c, 0xde, 0x8c, 0xce, 0xa9, 0x0b, 0xce, + 0x78, 0x4f, 0x98, 0xf2, 0x4f, 0x81, 0x6b, 0x72, 0xd9, 0x32, 0x39, 0xd1, + 0xeb, 0x0a, 0x38, 0x0e, 0xb7, 0x6e, 0x71, 0xc9, 0x5d, 0x9c, 0xe1, 0x94, + 0x2f, 0x9d, 0x89, 0x6b, 0xba, 0x11, 0xb9, 0xca, 0xbf, 0x72, 0xaa, 0x0c, + 0x39, 0xbf, 0xbd, 0xa6, 0x04, 0x3e, 0xee, 0x03, 0x41, 0xae, 0xf8, 0x37, + 0x94, 0x9f, 0x69, 0xc9, 0xbd, 0x34, 0xdf, 0x97, 0xfe, 0xaa, 0xf6, 0xfe, + 0x6f, 0xc2, 0xe3, 0x31, 0xd6, 0xb1, 0x58, 0x67, 0x53, 0xe5, 0xe7, 0x54, + 0xaf, 0xb8, 0xbf, 0x9e, 0xce, 0xd0, 0x1f, 0xc0, 0xb3, 0x44, 0x5f, 0xbf, + 0x3a, 0x29, 0x00, 0xd3, 0xf6, 0x86, 0x45, 0x65, 0x92, 0xdc, 0xe5, 0xa0, + 0xf6, 0x75, 0x1e, 0x37, 0x41, 0xa4, 0x22, 0xd0, 0xaa, 0xd9, 0xce, 0x81, + 0xb3, 0x3b, 0x54, 0x6a, 0x41, 0x90, 0x84, 0x9c, 0x2b, 0x9e, 0x5e, 0x71, + 0x88, 0xfa, 0xfc, 0x3c, 0xeb, 0x15, 0x89, 0xb0, 0xbf, 0xde, 0x2b, 0xd1, + 0x30, 0xb6, 0xaa, 0x24, 0x74, 0x2b, 0xef, 0xb0, 0x93, 0xa0, 0xaa, 0x12, + 0xf0, 0x6a, 0x7b, 0x7c, 0x13, 0x03, 0x71, 0x6b, 0xe7, 0x74, 0xd5, 0x4c, + 0x7c, 0x2f, 0xe7, 0xc8, 0x36, 0xc3, 0x0d, 0x8e, 0xc1, 0xfa, 0x1e, 0x8f, + 0x6d, 0x26, 0xde, 0x3e, 0xce, 0x87, 0xf7, 0x57, 0xbf, 0x63, 0x32, 0x9c, + 0xbc, 0xda, 0x72, 0xee, 0x1b, 0x88, 0x7b, 0xc6, 0xf5, 0xc5, 0x5a, 0xab, + 0x0d, 0xd0, 0x65, 0xea, 0xd6, 0xda, 0xd5, 0x19, 0xfd, 0xe9, 0xb7, 0x06, + 0x4e, 0x69, 0x2b, 0x63, 0x68, 0xdb, 0xe9, 0x56, 0x39, 0x3c, 0x3b, 0x83, + 0x6d, 0xa7, 0xf3, 0xeb, 0x75, 0x98, 0x61, 0x88, 0x18, 0xcb, 0x8c, 0xa5, + 0xbc, 0x32, 0x18, 0xdd, 0x3c, 0x88, 0xb5, 0x18, 0xcd, 0xec, 0x77, 0x6a, + 0x36, 0x35, 0xfa, 0xf4, 0xfd, 0x77, 0x2d, 0x27, 0xc0, 0xda, 0xd7, 0x96, + 0x04, 0x46, 0x18, 0x8c, 0xfe, 0x7c, 0x58, 0xb8, 0xe3, 0x88, 0xb2, 0x54, + 0x61, 0xc5, 0x16, 0x5f, 0x46, 0xd9, 0x64, 0xc7, 0x87, 0xfc, 0xc4, 0x44, + 0x32, 0x7b, 0x94, 0x67, 0x22, 0xbb, 0x47, 0xe2, 0xce, 0x50, 0xeb, 0x5c, + 0x4f, 0x0f, 0x83, 0xd0, 0xd7, 0x0e, 0x4e, 0x37, 0x0c, 0x45, 0x17, 0x0c, + 0x1f, 0x51, 0xca, 0x6d, 0x8d, 0xd2, 0xdf, 0x23, 0x6e, 0xf0, 0x4b, 0x43, + 0x51, 0x69, 0xd8, 0x97, 0x6e, 0x8d, 0xc4, 0x9f, 0xcd, 0x1e, 0x7e, 0x59, + 0xd9, 0x62, 0x4f, 0xc9, 0xf9, 0xb0, 0x3b, 0xb9, 0xcc, 0x81, 0x35, 0x9e, + 0x5c, 0xc6, 0xcb, 0x44, 0xa4, 0xbb, 0x96, 0xba, 0xd4, 0x23, 0x0a, 0x99, + 0x34, 0xc5, 0x71, 0xb3, 0x6f, 0xa9, 0x6c, 0x2a, 0x73, 0xa3, 0x66, 0x91, + 0xe6, 0x48, 0x97, 0x07, 0xa3, 0x9b, 0x86, 0x0b, 0x21, 0x42, 0xd3, 0x64, + 0x04, 0xe1, 0xf3, 0x14, 0x00, 0xba, 0x6f, 0xa6, 0x37, 0x99, 0xda, 0x54, + 0x4c, 0xce, 0x20, 0x0d, 0x53, 0xc2, 0x83, 0x51, 0x59, 0xb3, 0x3d, 0xbe, + 0xa7, 0xd8, 0x3c, 0xf3, 0x0e, 0x65, 0x59, 0x71, 0x11, 0x2c, 0x2f, 0x0e, + 0xfa, 0xde, 0xe0, 0xe7, 0x29, 0xcc, 0xf4, 0xdd, 0xbe, 0x05, 0x0b, 0x6e, + 0xf2, 0xfe, 0x8b, 0xf2, 0x7d, 0xc9, 0x1e, 0x29, 0xb7, 0x51, 0xaf, 0x80, + 0x66, 0xc5, 0x62, 0x7f, 0x52, 0x71, 0xf0, 0x6f, 0x28, 0x9f, 0xc8, 0x8f, + 0xc9, 0x44, 0xe0, 0x7d, 0x25, 0xf2, 0x0e, 0x79, 0xce, 0x82, 0xd1, 0x0a, + 0xdd, 0x3d, 0xe2, 0x2d, 0x23, 0x8d, 0x36, 0x25, 0x16, 0xdd, 0x1a, 0x23, + 0x8d, 0x83, 0x98, 0xd6, 0x68, 0x3b, 0x64, 0xcd, 0x93, 0x7f, 0x2d, 0x59, + 0x22, 0x29, 0xca, 0xac, 0xdb, 0x8e, 0x3b, 0xba, 0x6c, 0x3f, 0x52, 0x9e, + 0x91, 0x26, 0x87, 0xdf, 0x52, 0x06, 0xe5, 0x67, 0xe4, 0xf9, 0xb6, 0xef, + 0x61, 0x8a, 0x67, 0x4b, 0x89, 0x18, 0xf6, 0x63, 0x0a, 0x4c, 0x75, 0x45, + 0xf2, 0x6f, 0x3b, 0x20, 0x4d, 0x88, 0xdc, 0x02, 0x74, 0xff, 0xda, 0x1f, + 0xe5, 0x27, 0x65, 0x82, 0xf5, 0x4b, 0x63, 0x78, 0x73, 0x11, 0x4c, 0x3d, + 0x15, 0xa9, 0x13, 0xea, 0x60, 0xab, 0x94, 0xfa, 0x4e, 0xa7, 0xb9, 0xdc, + 0xd2, 0xe2, 0xbd, 0x53, 0xe9, 0x00, 0xba, 0xcf, 0xeb, 0x11, 0x3e, 0xa8, + 0xfc, 0x41, 0xde, 0x8e, 0xa9, 0x38, 0x2d, 0x1f, 0x53, 0x97, 0x17, 0x9f, + 0x50, 0x3b, 0xb4, 0xb4, 0xf5, 0xa8, 0x4b, 0x13, 0xb8, 0x29, 0xa3, 0x3b, + 0x1b, 0x2d, 0x85, 0xee, 0xd7, 0xe0, 0x57, 0x7c, 0x9b, 0xc2, 0x4e, 0xfa, + 0x99, 0xb6, 0xd3, 0xab, 0xce, 0xba, 0xd5, 0xbb, 0x48, 0xa1, 0x3b, 0xe0, + 0xde, 0xc6, 0x38, 0x7e, 0x21, 0x7f, 0x2a, 0x3f, 0xa3, 0xa6, 0x4d, 0x61, + 0x3a, 0xb3, 0xa1, 0xdc, 0xfd, 0xa9, 0x7a, 0x17, 0x9e, 0xf1, 0x89, 0xd5, + 0xee, 0x0f, 0xd5, 0xe7, 0x05, 0x2f, 0xf5, 0x6f, 0xdf, 0xd9, 0x99, 0xf8, + 0xb0, 0xbb, 0x5b, 0x4d, 0x5c, 0xf8, 0xcf, 0x42, 0x9b, 0x74, 0xba, 0xb3, + 0x31, 0xe9, 0x7b, 0xee, 0x77, 0xd5, 0x17, 0x94, 0x9f, 0x21, 0xaf, 0x5c, + 0xa1, 0xbc, 0xac, 0xed, 0xf4, 0xfa, 0x9b, 0x72, 0x5a, 0xdb, 0x77, 0xb5, + 0x4b, 0xdf, 0x93, 0x74, 0x79, 0xff, 0x55, 0x6f, 0x5b, 0x50, 0xf9, 0xc1, + 0x21, 0x6a, 0xd7, 0x85, 0x6d, 0xd0, 0xda, 0xab, 0x36, 0xde, 0xb7, 0xbd, + 0xde, 0x61, 0xba, 0xe7, 0x54, 0x22, 0xb6, 0xd8, 0x6f, 0x87, 0x8b, 0x14, + 0xc6, 0xc5, 0x04, 0x5b, 0xeb, 0xe3, 0x56, 0xed, 0x36, 0x44, 0x88, 0x8b, + 0x38, 0xed, 0x48, 0xd7, 0x10, 0x79, 0xa1, 0x07, 0x79, 0x77, 0x03, 0xd7, + 0xc0, 0x69, 0xfc, 0x76, 0xec, 0x7b, 0x90, 0x9d, 0x14, 0xb1, 0x43, 0x02, + 0xb6, 0x02, 0xa6, 0xf7, 0x44, 0x3f, 0x17, 0xa2, 0x63, 0x3c, 0x54, 0x9a, + 0x24, 0xee, 0xad, 0x48, 0x57, 0x24, 0xc4, 0x35, 0x1b, 0x50, 0xba, 0x86, + 0xd3, 0x86, 0x9d, 0x82, 0xe2, 0x0a, 0x54, 0x04, 0x1a, 0x24, 0xe8, 0xe4, + 0xde, 0xdb, 0xaf, 0xb4, 0xf0, 0x86, 0xe6, 0xe7, 0x25, 0x38, 0x3b, 0xdc, + 0x93, 0x0f, 0xb9, 0xf8, 0xad, 0x61, 0x40, 0x54, 0x9c, 0x50, 0x6e, 0x63, + 0x1b, 0xa9, 0x2d, 0x80, 0x25, 0xc3, 0x90, 0xbd, 0x2e, 0x42, 0xb0, 0xff, + 0x2f, 0xc7, 0x50, 0x0c, 0x11, 0x27, 0xb0, 0xc8, 0x31, 0x6e, 0xc7, 0xbb, + 0x4a, 0x84, 0x0b, 0x6d, 0xb4, 0x95, 0x3b, 0xb8, 0x20, 0xb6, 0x5c, 0x47, + 0xbb, 0xfc, 0x72, 0xe4, 0xc7, 0x2a, 0x7d, 0x4a, 0x7a, 0x7b, 0x51, 0xc2, + 0xdc, 0xaf, 0x79, 0x42, 0x7d, 0x4a, 0x65, 0x42, 0x74, 0x0f, 0x2d, 0x13, + 0x5a, 0xaa, 0x98, 0x3d, 0x74, 0x75, 0xdb, 0xc5, 0xf0, 0xda, 0x05, 0xda, + 0xdc, 0xdf, 0xe9, 0x54, 0x20, 0xcd, 0xce, 0x15, 0x6c, 0x63, 0x9c, 0xae, + 0xe7, 0x74, 0x93, 0xd0, 0x14, 0xbb, 0x83, 0x27, 0x18, 0x1a, 0x6f, 0x7f, + 0x49, 0xfe, 0x34, 0x52, 0x8b, 0x52, 0xd9, 0x78, 0x20, 0xc1, 0x0f, 0xb5, + 0x30, 0xa8, 0x7d, 0xae, 0x72, 0x2d, 0x24, 0x1a, 0x0e, 0xed, 0x1b, 0xbe, + 0x0c, 0xd7, 0x61, 0x4f, 0x82, 0x0a, 0x80, 0x72, 0x40, 0xb1, 0x4b, 0x95, + 0x61, 0x12, 0x6a, 0x91, 0x0a, 0x3b, 0x1b, 0xc4, 0x2e, 0xb0, 0x4b, 0x05, + 0x61, 0x67, 0xc0, 0x67, 0x67, 0x05, 0x43, 0xb0, 0x22, 0xb0, 0xc4, 0x67, + 0x08, 0xbd, 0x96, 0x72, 0x23, 0x4f, 0x1a, 0x89, 0xc7, 0xc1, 0x6f, 0xb4, + 0xbe, 0x48, 0xf7, 0xfd, 0xc3, 0x9d, 0x86, 0xd9, 0xa7, 0xf2, 0x31, 0xb5, + 0x83, 0xd1, 0xf7, 0xfa, 0x0d, 0x19, 0x09, 0x91, 0x24, 0x91, 0x6d, 0x4e, + 0x95, 0x2f, 0xf7, 0x4d, 0xfb, 0x54, 0x6e, 0x27, 0xd9, 0xf9, 0xa6, 0x6a, + 0x68, 0x76, 0x06, 0x2e, 0x45, 0xbf, 0x3f, 0xdc, 0x5a, 0x5f, 0xbc, 0xc0, + 0xee, 0xad, 0x13, 0xe9, 0x33, 0x43, 0x28, 0xd3, 0x7f, 0x9e, 0xcf, 0x94, + 0x97, 0xfb, 0x49, 0xcb, 0x45, 0xfb, 0xd3, 0x32, 0xd9, 0xdb, 0x86, 0x21, + 0xce, 0xc0, 0xb2, 0xe3, 0x9a, 0x04, 0x85, 0xe9, 0xad, 0xea, 0x6f, 0x55, + 0xca, 0x1d, 0xad, 0xb2, 0xa8, 0x2c, 0xb5, 0x65, 0xca, 0x5c, 0x28, 0x64, + 0xe3, 0x30, 0xbd, 0x21, 0x07, 0xcd, 0xd9, 0x5e, 0xc7, 0x6f, 0xe4, 0x7d, + 0x91, 0x44, 0x75, 0xba, 0x56, 0x4e, 0xa3, 0x87, 0x0c, 0x19, 0x7f, 0x8e, + 0x38, 0x03, 0xb4, 0x44, 0x4b, 0x86, 0xeb, 0x5c, 0xad, 0xf5, 0x41, 0x0c, + 0xff, 0xdf, 0x54, 0x31, 0xb0, 0x55, 0x62, 0x4f, 0x2c, 0x0f, 0x90, 0xd0, + 0x5e, 0x69, 0xdc, 0x69, 0x9a, 0x2f, 0x38, 0x3d, 0x5e, 0x0b, 0x9f, 0xe9, + 0xbd, 0x11, 0x43, 0x77, 0x61, 0xf8, 0x8b, 0x6d, 0x53, 0xa1, 0x55, 0x76, + 0xc9, 0x90, 0xf7, 0x47, 0xbd, 0x4e, 0xb6, 0x0e, 0x41, 0xf6, 0xeb, 0xe1, + 0x16, 0x95, 0x34, 0xa7, 0x97, 0x59, 0x81, 0x5a, 0x37, 0x70, 0x94, 0xe4, + 0x43, 0x5f, 0x94, 0xa0, 0x26, 0xc2, 0x35, 0xfb, 0x7c, 0xb4, 0xac, 0x0f, + 0xac, 0x78, 0x76, 0xbe, 0x31, 0xe3, 0x97, 0x67, 0x1f, 0xc7, 0x32, 0x05, + 0x21, 0x03, 0xf5, 0x4b, 0x4e, 0x2f, 0xd1, 0xae, 0x8f, 0x0d, 0x28, 0x55, + 0x98, 0xcf, 0x1e, 0x58, 0x31, 0x1d, 0xe8, 0x9b, 0xcf, 0xce, 0x37, 0x64, + 0x40, 0x37, 0xa3, 0x6e, 0xc0, 0x32, 0xc8, 0xc7, 0x56, 0xd1, 0x7f, 0xc9, + 0xd0, 0xdc, 0xaa, 0x8c, 0x81, 0x90, 0x9d, 0xe6, 0x2c, 0xc4, 0x8b, 0xf2, + 0x85, 0x8f, 0x51, 0x5e, 0x1b, 0x8c, 0x6d, 0xde, 0x3c, 0x10, 0xd3, 0x96, + 0x90, 0xd2, 0x71, 0x63, 0x06, 0x5b, 0x34, 0x17, 0x48, 0x9b, 0x9e, 0x0a, + 0x8f, 0x1d, 0xba, 0x63, 0xd4, 0x2b, 0x52, 0x7e, 0xf7, 0x11, 0xd4, 0x20, + 0x26, 0x64, 0x91, 0x60, 0x22, 0x1c, 0x00, 0x8f, 0xf7, 0x6e, 0x1b, 0x4a, + 0x00, 0x52, 0x52, 0x64, 0x2c, 0x90, 0xa6, 0x27, 0xb1, 0xb6, 0x48, 0x13, + 0x88, 0xec, 0xcc, 0x27, 0x25, 0x72, 0xe2, 0x03, 0x07, 0x1d, 0x61, 0xb4, + 0xf5, 0x08, 0x4e, 0x94, 0x13, 0xf6, 0xbe, 0x69, 0x67, 0x83, 0xcc, 0xdb, + 0x0c, 0x6a, 0x80, 0xa7, 0xbd, 0xb0, 0xa3, 0x4d, 0x1a, 0xdb, 0x49, 0xf6, + 0x82, 0x48, 0x6e, 0x6c, 0x93, 0x18, 0xed, 0x4d, 0xae, 0x08, 0x9a, 0xf0, + 0x6d, 0x99, 0x5a, 0x58, 0xe0, 0x3c, 0x4d, 0xf6, 0x7a, 0x2b, 0xf1, 0x07, + 0xb1, 0x4f, 0x06, 0xd1, 0xe7, 0xa7, 0xbb, 0x7d, 0x3d, 0x0a, 0xdb, 0xb4, + 0xdd, 0x0b, 0x4d, 0x36, 0x5f, 0x45, 0x31, 0x73, 0x6c, 0x4f, 0x31, 0x0d, + 0x8b, 0x86, 0x74, 0x5a, 0x35, 0x1f, 0x37, 0xbf, 0xf6, 0xaa, 0xca, 0x80, + 0x7b, 0x16, 0x0b, 0x96, 0x5c, 0xa6, 0x53, 0x28, 0xea, 0x3c, 0x5c, 0x33, + 0x9f, 0x01, 0xff, 0x2c, 0x43, 0x2e, 0xe9, 0x9c, 0x5f, 0x14, 0x55, 0xed, + 0x30, 0x67, 0x16, 0x08, 0x86, 0xdc, 0x2f, 0x3b, 0x27, 0x15, 0xf5, 0x6a, + 0x7b, 0x29, 0x12, 0x82, 0x47, 0xb5, 0xd5, 0x5e, 0x96, 0x1d, 0x3c, 0x30, + 0x3b, 0x4d, 0xc1, 0xa1, 0x68, 0xd7, 0x20, 0xe3, 0x32, 0x85, 0x16, 0x4b, + 0xd8, 0x5e, 0x8b, 0x1c, 0xb5, 0x6c, 0x03, 0x5d, 0x4f, 0x64, 0x53, 0xb6, + 0xa7, 0x2f, 0xb6, 0x47, 0xb0, 0x05, 0x9b, 0x77, 0x90, 0x26, 0x94, 0x1c, + 0x6b, 0xdd, 0xd9, 0x51, 0x94, 0x6f, 0x8e, 0xc7, 0x40, 0x4c, 0x07, 0x2e, + 0xd8, 0x88, 0x3d, 0x17, 0xdb, 0x6c, 0xd2, 0x56, 0xbe, 0xbe, 0x3e, 0x64, + 0x82, 0x7d, 0x12, 0x84, 0x57, 0xf6, 0x90, 0x10, 0xdb, 0xdc, 0x78, 0x5f, + 0x0b, 0x1f, 0x8b, 0xb6, 0xc5, 0x88, 0xc8, 0x05, 0xf7, 0x49, 0xee, 0x30, + 0xd9, 0x4d, 0x42, 0x3c, 0x7e, 0x6d, 0xc1, 0xaf, 0x9f, 0x8f, 0x49, 0x92, + 0x34, 0x87, 0x88, 0x93, 0x81, 0xdb, 0x89, 0x32, 0x55, 0x0b, 0x87, 0x5f, + 0x50, 0xca, 0x3e, 0xaf, 0x92, 0x19, 0xd9, 0xb5, 0x31, 0xd4, 0xec, 0x4c, + 0x19, 0x97, 0x22, 0xd9, 0xa0, 0x85, 0xdc, 0x1b, 0xc2, 0x36, 0x70, 0x43, + 0x04, 0x26, 0x9b, 0x22, 0x6c, 0xe8, 0x3c, 0x3f, 0x19, 0xe8, 0x1b, 0xf5, + 0x31, 0xba, 0x1e, 0xa6, 0xd2, 0xf1, 0x0c, 0xb0, 0x3d, 0x64, 0xc6, 0x57, + 0x2a, 0xdd, 0xaf, 0x4d, 0x67, 0x2d, 0xa6, 0x42, 0xd0, 0xb7, 0x28, 0x6f, + 0x7c, 0x64, 0x65, 0x6d, 0x5e, 0xde, 0xe4, 0xf0, 0x94, 0xbc, 0xa9, 0x28, + 0x51, 0x56, 0xa7, 0x1b, 0x83, 0xee, 0x5a, 0x3a, 0xf6, 0xef, 0xcb, 0xe8, + 0x3a, 0xcc, 0xe7, 0xe5, 0x75, 0x5a, 0x0b, 0x39, 0xa8, 0xc1, 0x3b, 0xcb, + 0xb5, 0x3b, 0xe4, 0x46, 0x3e, 0x2f, 0xfd, 0xb4, 0x91, 0xf6, 0x38, 0xe1, + 0x4a, 0xe9, 0x56, 0x9b, 0x45, 0xf3, 0xed, 0x0a, 0x79, 0xb6, 0x30, 0x64, + 0x99, 0xb5, 0xb5, 0x23, 0xc6, 0x1b, 0xdd, 0x40, 0xf7, 0x38, 0x10, 0x11, + 0x26, 0x61, 0x6a, 0x83, 0xc7, 0x55, 0xba, 0x02, 0xe3, 0x67, 0xe9, 0x27, + 0x50, 0x2a, 0xe8, 0x57, 0x13, 0xc4, 0xfb, 0x7c, 0x13, 0x79, 0xeb, 0xec, + 0x53, 0xea, 0x54, 0xe8, 0x41, 0xde, 0xcd, 0x35, 0x9d, 0xb3, 0x93, 0x22, + 0x53, 0x5e, 0xc2, 0x59, 0x43, 0x23, 0xf4, 0x76, 0xf4, 0x73, 0x19, 0x66, + 0xd4, 0x07, 0xfe, 0xdd, 0x59, 0x59, 0x56, 0x55, 0xd2, 0x17, 0xad, 0x19, + 0x22, 0xf9, 0xe5, 0xd6, 0xcf, 0x55, 0x16, 0xd2, 0x3c, 0x5c, 0xd0, 0x82, + 0xb2, 0x41, 0x06, 0x18, 0x83, 0xd4, 0xaf, 0x84, 0xf7, 0x84, 0xa5, 0x85, + 0x0b, 0x79, 0x7f, 0x7f, 0xde, 0xfe, 0x82, 0xd5, 0x0d, 0x99, 0x7e, 0xe8, + 0x6d, 0x1e, 0x60, 0x42, 0xab, 0x89, 0x43, 0x99, 0x8a, 0xb2, 0xc0, 0x5e, + 0xe9, 0xde, 0xee, 0x8b, 0xf6, 0x7c, 0x6d, 0x6d, 0xe7, 0xdd, 0x31, 0x43, + 0xc6, 0xd8, 0x30, 0xc9, 0x9c, 0xe0, 0xcc, 0x86, 0x75, 0x19, 0x36, 0xef, + 0x36, 0x2f, 0x81, 0x7b, 0x47, 0x71, 0x8d, 0x3b, 0x61, 0xf4, 0x92, 0x04, + 0xc9, 0x12, 0x3e, 0x28, 0x19, 0xbb, 0x05, 0xf8, 0x45, 0x06, 0xf4, 0x7a, + 0x63, 0xcc, 0x0c, 0x3a, 0x72, 0xc0, 0x64, 0xc6, 0x7d, 0xbe, 0x37, 0x0d, + 0x1f, 0xb5, 0x31, 0xa1, 0x90, 0xc2, 0x06, 0x8f, 0x48, 0xd2, 0x19, 0x27, + 0xd0, 0x14, 0xbe, 0x88, 0xda, 0xf8, 0xe8, 0xe6, 0xd6, 0xac, 0x54, 0x79, + 0xbb, 0xba, 0x32, 0xc3, 0x1c, 0x4c, 0x6c, 0x76, 0xd4, 0x06, 0xa5, 0xb4, + 0xb0, 0x31, 0x24, 0xa0, 0x0e, 0x61, 0x09, 0x79, 0x8f, 0x41, 0x96, 0x25, + 0x68, 0xfc, 0x17, 0x33, 0xd6, 0x5f, 0x2c, 0xfa, 0xd6, 0x70, 0x8a, 0xc8, + 0x7b, 0x51, 0x97, 0x6a, 0x69, 0xf4, 0x72, 0x1e, 0xa3, 0xcf, 0x18, 0xdc, + 0x87, 0xa5, 0xc0, 0x36, 0xb7, 0xd8, 0xcd, 0x74, 0x17, 0x32, 0xd2, 0xf5, + 0xfb, 0x27, 0xb2, 0x81, 0xd6, 0xdb, 0x51, 0xcd, 0x46, 0xec, 0x0e, 0x2c, + 0x11, 0xc8, 0xdc, 0x2b, 0x1d, 0x3b, 0xb3, 0xd7, 0xe1, 0x44, 0xdd, 0x99, + 0xc6, 0xd8, 0x38, 0xa8, 0xe5, 0x1e, 0x8e, 0x62, 0x3f, 0xfb, 0x6b, 0xa4, + 0xda, 0xfb, 0x95, 0xdf, 0x48, 0x6b, 0xb1, 0xaf, 0xbc, 0x88, 0x5a, 0xf3, + 0xcc, 0xb3, 0x4c, 0xa8, 0x4b, 0x61, 0x50, 0x27, 0x61, 0xf3, 0xb2, 0xc3, + 0x24, 0xcf, 0x86, 0xfd, 0xf4, 0x8b, 0xd2, 0xd8, 0x08, 0xc9, 0x4b, 0x46, + 0x69, 0x7b, 0x59, 0x16, 0xed, 0x2f, 0x49, 0x73, 0x42, 0xc8, 0x8e, 0x12, + 0x00, 0xd7, 0x2c, 0xfa, 0x53, 0xe5, 0xd1, 0xa1, 0x74, 0x79, 0xaa, 0x4a, + 0x9a, 0x04, 0x20, 0x33, 0xa1, 0xf7, 0x75, 0xec, 0xc5, 0x3f, 0x8b, 0xc4, + 0x73, 0x56, 0xac, 0xe5, 0x6c, 0x11, 0xe6, 0x2c, 0x43, 0x4d, 0xa5, 0xbd, + 0x6b, 0xa4, 0x5b, 0x3b, 0x9e, 0x89, 0xfc, 0x0d, 0x65, 0x03, 0xba, 0x76, + 0x8c, 0xea, 0x63, 0x4f, 0x22, 0x1e, 0xce, 0x80, 0x29, 0xd3, 0x22, 0x30, + 0x8d, 0x0b, 0xcf, 0xd4, 0x4a, 0xf8, 0xa7, 0xc3, 0x06, 0x98, 0x20, 0x7e, + 0x67, 0xd4, 0x04, 0x6f, 0x46, 0xd1, 0x11, 0x2f, 0xd7, 0xb4, 0x13, 0x16, + 0x2f, 0xa1, 0xde, 0x42, 0x18, 0x71, 0xbc, 0x8f, 0x84, 0xf2, 0x21, 0xe4, + 0x60, 0xb2, 0x04, 0xcd, 0xae, 0x78, 0xef, 0x10, 0x13, 0x7a, 0x40, 0x81, + 0x29, 0x73, 0xc2, 0xf1, 0x74, 0x5b, 0xc3, 0x71, 0x1b, 0x9a, 0xc6, 0xc8, + 0xf3, 0x26, 0xee, 0x14, 0xd7, 0x6c, 0x55, 0x0c, 0xbe, 0xf1, 0xd8, 0x3b, + 0x58, 0xc5, 0x69, 0x3d, 0x24, 0xf3, 0xa4, 0x4a, 0xb2, 0x3e, 0xc1, 0xf2, + 0xa2, 0x7b, 0xb7, 0x52, 0xe9, 0x0e, 0xdb, 0xbc, 0xbf, 0x87, 0xc5, 0x00, + 0x08, 0x6c, 0x10, 0xe9, 0x3f, 0x28, 0x62, 0x9f, 0x96, 0xe6, 0x69, 0xe2, + 0xed, 0xca, 0xdd, 0xe9, 0x19, 0xa8, 0x33, 0xd9, 0x65, 0x91, 0xce, 0xa8, + 0x4c, 0xf5, 0x46, 0x98, 0x66, 0xd2, 0x34, 0x5a, 0x21, 0xb3, 0x1e, 0x47, + 0xb9, 0x61, 0xc1, 0xa8, 0x09, 0x4e, 0x82, 0x75, 0x4d, 0xbc, 0x44, 0x30, + 0xc0, 0x93, 0xde, 0x13, 0x4b, 0xf2, 0x90, 0xea, 0x48, 0x96, 0x20, 0x66, + 0xf8, 0x68, 0x59, 0x24, 0x84, 0x26, 0xc8, 0x4f, 0x7f, 0x4c, 0x8e, 0x35, + 0x49, 0x67, 0x3a, 0xd9, 0xd0, 0x7e, 0x25, 0x28, 0x8d, 0xeb, 0xaa, 0x50, + 0x0c, 0x8d, 0xf7, 0xa4, 0x43, 0xef, 0xa6, 0x4b, 0x86, 0x0c, 0x16, 0x5b, + 0xe3, 0xa3, 0xce, 0xf4, 0xb2, 0x5f, 0x7f, 0xec, 0x04, 0xf1, 0x8a, 0x16, + 0x7a, 0x29, 0xfa, 0x3f, 0x06, 0xe2, 0xa5, 0x76, 0xf0, 0xd2, 0x64, 0xbc, + 0x7f, 0x6f, 0xba, 0xcb, 0x4f, 0x5c, 0x9c, 0x27, 0x04, 0x1f, 0xf0, 0xf7, + 0xca, 0x2f, 0xab, 0xae, 0x00, 0xdb, 0xf4, 0xb8, 0x64, 0xe9, 0x8e, 0x5b, + 0x17, 0xd9, 0x80, 0xb9, 0x26, 0x37, 0x85, 0x94, 0x23, 0xd2, 0x6f, 0xcf, + 0x74, 0x7d, 0x3c, 0xc1, 0x45, 0x5a, 0xb0, 0x77, 0xc8, 0x1a, 0xe3, 0x1d, + 0x25, 0x1d, 0x09, 0x73, 0xcd, 0x21, 0x9e, 0x2b, 0xe2, 0x15, 0xe8, 0x9d, + 0xd5, 0x2f, 0x88, 0x4b, 0x1d, 0xcf, 0x4a, 0x1f, 0x76, 0x51, 0xbb, 0x5d, + 0xb4, 0xac, 0xcd, 0x62, 0x4d, 0x9b, 0x90, 0xd9, 0x6c, 0xdf, 0x09, 0x2f, + 0xd8, 0x7d, 0x8a, 0x51, 0x49, 0x87, 0x7f, 0xf5, 0x9e, 0xf0, 0x16, 0xf8, + 0x38, 0xd9, 0x27, 0x73, 0xee, 0x6d, 0xd2, 0x85, 0x13, 0x74, 0x96, 0x8c, + 0x55, 0x92, 0xe8, 0x3c, 0xe5, 0x64, 0x26, 0x42, 0x67, 0xc8, 0xdc, 0xed, + 0xf6, 0xda, 0x31, 0x30, 0xe7, 0x66, 0xdb, 0x14, 0xe8, 0x14, 0xa6, 0x53, + 0x2f, 0xa8, 0x9f, 0x87, 0x41, 0xf8, 0x12, 0x7b, 0xb1, 0x44, 0x65, 0xfb, + 0x21, 0xb2, 0x93, 0x34, 0xdd, 0x3b, 0x6a, 0x27, 0x3c, 0xce, 0x33, 0x3b, + 0x6d, 0x30, 0xc1, 0x35, 0xca, 0x6b, 0x6e, 0x30, 0xee, 0x48, 0x95, 0xa8, + 0x35, 0x25, 0x0e, 0x79, 0x00, 0xf2, 0x84, 0xcc, 0x8c, 0x09, 0x37, 0x41, + 0x01, 0x6a, 0x8e, 0x33, 0x64, 0x87, 0x62, 0xda, 0x6d, 0x08, 0xb2, 0xbb, + 0x0d, 0x21, 0xba, 0x4e, 0xd2, 0x10, 0x2a, 0xaf, 0xe5, 0x82, 0x80, 0xed, + 0x8c, 0x43, 0x5e, 0xf3, 0x00, 0xf6, 0x33, 0x77, 0x21, 0xff, 0x17, 0xf2, + 0x6c, 0x58, 0x6e, 0x26, 0xe4, 0x1c, 0xa3, 0xbb, 0x5f, 0x91, 0x8c, 0xef, + 0x98, 0xa6, 0x70, 0x67, 0x73, 0x61, 0xa6, 0x46, 0x3f, 0x3f, 0x8e, 0x91, + 0x90, 0x39, 0x73, 0x8f, 0x64, 0x38, 0x3d, 0x69, 0x02, 0x64, 0xce, 0x06, + 0x36, 0x74, 0xb3, 0x6c, 0xc2, 0x7e, 0xd2, 0x10, 0x3c, 0xa5, 0x72, 0xa1, + 0x9c, 0xbc, 0x7b, 0x22, 0x86, 0x90, 0xb9, 0x99, 0xf1, 0xa4, 0x6a, 0x33, + 0x38, 0x8b, 0xc3, 0xd7, 0x7f, 0xbf, 0x19, 0xbf, 0xdf, 0x23, 0xcd, 0x38, + 0x6d, 0x07, 0x11, 0x98, 0x37, 0x99, 0xdf, 0xee, 0x95, 0x06, 0xde, 0x61, + 0x42, 0xfe, 0xf4, 0x33, 0x19, 0x9c, 0xb8, 0x43, 0x32, 0x74, 0x62, 0x9a, + 0x8b, 0x1c, 0x8e, 0x90, 0x99, 0x60, 0xb9, 0x93, 0xe6, 0x13, 0x3c, 0xb8, + 0xb8, 0x63, 0x7b, 0xa5, 0xc1, 0x77, 0xa8, 0x05, 0x0d, 0xd4, 0xe7, 0x91, + 0x77, 0x66, 0xa1, 0x2c, 0xe7, 0x91, 0x0d, 0x42, 0x66, 0x0f, 0x1b, 0x22, + 0x33, 0x88, 0x87, 0x0d, 0x9a, 0xa7, 0x18, 0xbb, 0x69, 0xa8, 0x47, 0x4e, + 0x53, 0x1f, 0x52, 0xdc, 0x6c, 0x51, 0x4e, 0x71, 0x89, 0x8a, 0xd5, 0xeb, + 0x20, 0xbc, 0x4f, 0x90, 0x0f, 0xd1, 0xd5, 0x95, 0x79, 0xff, 0x1e, 0x16, + 0x9c, 0xc6, 0x66, 0x26, 0x54, 0x6f, 0xa7, 0x6b, 0x69, 0xfe, 0xe0, 0xe5, + 0x8a, 0x6c, 0x0a, 0xb5, 0x7c, 0xf3, 0x8e, 0xca, 0xdd, 0x12, 0x56, 0x39, + 0x81, 0xee, 0x48, 0xa8, 0x69, 0x4b, 0xcb, 0x48, 0xbc, 0x9d, 0x7a, 0x8c, + 0xaf, 0x69, 0xb7, 0x42, 0x42, 0x29, 0xe9, 0x3d, 0x89, 0xfa, 0x6f, 0x34, + 0x4c, 0xc7, 0x3a, 0x49, 0xef, 0xdb, 0x78, 0xfe, 0x45, 0x58, 0x00, 0x03, + 0xde, 0x7f, 0x03, 0xcf, 0xcf, 0x61, 0x1d, 0x7c, 0xa6, 0x6e, 0x1d, 0x06, + 0xeb, 0x49, 0x7d, 0x6d, 0xd9, 0x2e, 0x91, 0x59, 0x50, 0x0e, 0xe1, 0xfb, + 0xa8, 0xfd, 0xa6, 0xcb, 0xeb, 0x02, 0x38, 0xb8, 0xa8, 0xcf, 0xff, 0x53, + 0xbb, 0x7d, 0x35, 0xed, 0xbd, 0xee, 0x9a, 0xf9, 0x74, 0xbd, 0xfc, 0xae, + 0xc4, 0xf8, 0xba, 0x79, 0x7a, 0xbc, 0x7e, 0x8e, 0x92, 0xf4, 0x16, 0x0e, + 0x7d, 0xd3, 0xfc, 0xe3, 0x4d, 0x6d, 0xc6, 0x16, 0xe6, 0x36, 0xd8, 0xfd, + 0x61, 0xc1, 0x44, 0x65, 0xdf, 0xfc, 0x5b, 0xda, 0x69, 0x1c, 0x8f, 0x1c, + 0xa2, 0xab, 0x8c, 0xc8, 0x73, 0xd6, 0x0c, 0x63, 0x98, 0x6a, 0xb7, 0xa9, + 0xb5, 0x89, 0xb2, 0x55, 0xf3, 0xe4, 0xc4, 0x1c, 0x42, 0x0e, 0x88, 0xd2, + 0x5a, 0xbf, 0x5a, 0xd3, 0x36, 0x6f, 0x05, 0x9d, 0xaf, 0x87, 0x29, 0x74, + 0x4e, 0x6e, 0x00, 0x35, 0x0b, 0x26, 0xa3, 0x66, 0x19, 0x17, 0x59, 0xee, + 0xb4, 0x95, 0xd9, 0xb0, 0x47, 0x7e, 0xa6, 0x7f, 0x1e, 0x4a, 0xce, 0x06, + 0xf9, 0xf7, 0xf2, 0x86, 0x15, 0xe7, 0x30, 0xce, 0xd4, 0xf0, 0xba, 0x15, + 0xfb, 0xa1, 0x0b, 0xe5, 0x01, 0x6c, 0xc3, 0xd9, 0x7c, 0x84, 0x38, 0x93, + 0xe1, 0x80, 0x77, 0xc5, 0x78, 0x37, 0xec, 0x84, 0x01, 0x6d, 0x47, 0x76, + 0x52, 0x78, 0x2e, 0x7e, 0x91, 0xdc, 0xe3, 0x74, 0x71, 0x28, 0x99, 0x0e, + 0x44, 0xd7, 0x0c, 0xae, 0x5b, 0xf1, 0x89, 0xdc, 0x85, 0xdf, 0xbe, 0xa7, + 0xad, 0xf2, 0x67, 0x14, 0xbb, 0x8c, 0x32, 0x80, 0xff, 0x98, 0xdc, 0xa7, + 0xcf, 0x6b, 0x9c, 0xd1, 0x74, 0xfe, 0xe2, 0x15, 0x9a, 0x0e, 0x37, 0x35, + 0x9e, 0x8e, 0xe1, 0x21, 0x26, 0x43, 0xc1, 0x74, 0x3c, 0xee, 0xb4, 0x94, + 0x59, 0x30, 0x1d, 0x15, 0xfd, 0xc5, 0xf2, 0xf7, 0x65, 0xa3, 0xfc, 0x9a, + 0x8c, 0xbc, 0x2e, 0xbc, 0x72, 0xc5, 0x32, 0xa5, 0x4b, 0xd9, 0xa9, 0x8d, + 0x98, 0xbb, 0xe4, 0x74, 0x2c, 0x85, 0xcb, 0xe1, 0x44, 0xdb, 0x6e, 0x40, + 0x19, 0x39, 0x09, 0xc6, 0x03, 0x08, 0x29, 0x81, 0xb4, 0x1b, 0x3d, 0x0a, + 0x71, 0x5f, 0x9d, 0x4d, 0x4d, 0x4e, 0x2a, 0xb7, 0x8d, 0x4f, 0xaa, 0x3f, + 0xec, 0xe0, 0xca, 0x79, 0xf3, 0x6b, 0x3f, 0x90, 0x3e, 0x3f, 0x0b, 0x53, + 0x5c, 0xe1, 0x56, 0xa4, 0x54, 0xdb, 0xd9, 0x0a, 0x85, 0x60, 0x2f, 0x40, + 0xfd, 0xdc, 0x1b, 0x51, 0x93, 0x63, 0xa0, 0xcd, 0x99, 0x54, 0x96, 0x8c, + 0x31, 0x67, 0xf5, 0x5f, 0xdb, 0x13, 0xd4, 0x5e, 0x72, 0x02, 0xb5, 0xca, + 0xfd, 0x74, 0xac, 0x00, 0x8a, 0xc6, 0xd3, 0x1e, 0x60, 0xa9, 0xfc, 0xdd, + 0x74, 0xd1, 0x4f, 0xad, 0x24, 0xc6, 0xe9, 0x38, 0x9e, 0x0e, 0x23, 0xf0, + 0x98, 0x1f, 0xb3, 0xdb, 0xe2, 0x24, 0xc1, 0x31, 0x28, 0x95, 0xdd, 0xd8, + 0x8f, 0x1c, 0xd2, 0xb9, 0x55, 0x4a, 0xe8, 0x72, 0x6b, 0xba, 0x26, 0xd1, + 0x38, 0x9f, 0xad, 0xcc, 0x5e, 0xf2, 0x76, 0x7e, 0x5f, 0xf4, 0xcb, 0x4b, + 0xe5, 0x40, 0xf2, 0x3f, 0x57, 0xcd, 0x21, 0x9f, 0x1f, 0x39, 0x86, 0xdf, + 0x32, 0x85, 0xef, 0x16, 0xc1, 0xe2, 0x99, 0x00, 0x10, 0xac, 0xb4, 0x15, + 0xd5, 0x26, 0xb8, 0xdc, 0xe0, 0x2e, 0x8a, 0x45, 0x7f, 0x14, 0x23, 0x37, + 0x11, 0x78, 0x46, 0xfa, 0x2a, 0x32, 0x19, 0x20, 0x64, 0x9e, 0x9d, 0x6e, + 0x9b, 0x86, 0xba, 0xf2, 0x8f, 0x25, 0xae, 0xcb, 0x8c, 0xf1, 0x5b, 0x32, + 0x13, 0x0a, 0x2e, 0xaa, 0x15, 0x8e, 0xae, 0xa5, 0x97, 0xdf, 0x7f, 0x58, + 0x7b, 0xff, 0xbc, 0x7a, 0x39, 0x5d, 0x2c, 0x30, 0x49, 0xd8, 0x32, 0x50, + 0x72, 0x72, 0x70, 0x56, 0xb7, 0xfd, 0x06, 0x12, 0x31, 0xbb, 0x1d, 0x8c, + 0x3d, 0x85, 0x44, 0x38, 0xb7, 0x83, 0x34, 0xe3, 0x91, 0x71, 0x87, 0x80, + 0xee, 0x9b, 0x24, 0xee, 0x72, 0x80, 0x93, 0x82, 0x50, 0x33, 0x9f, 0x55, + 0x18, 0x30, 0x39, 0x79, 0x30, 0xa3, 0x16, 0x92, 0x1c, 0x36, 0x22, 0xb1, + 0x26, 0x4a, 0x58, 0x42, 0x6e, 0x16, 0xf5, 0x9d, 0x37, 0xbd, 0x66, 0xa0, + 0xfe, 0xce, 0x43, 0xe6, 0x54, 0x79, 0x40, 0x6d, 0x3a, 0x4c, 0xbd, 0xa1, + 0x5b, 0x05, 0x47, 0xd2, 0x69, 0xed, 0x0c, 0xc3, 0x4e, 0xb0, 0x99, 0xb4, + 0xb0, 0x2d, 0x4d, 0x26, 0x2d, 0x6c, 0xf3, 0x69, 0xd3, 0xa7, 0x27, 0x31, + 0x6c, 0xf3, 0xc7, 0x11, 0x41, 0x78, 0x5f, 0xb5, 0xa2, 0x3e, 0x4c, 0x9c, + 0xb1, 0xe8, 0x11, 0xcd, 0x37, 0xd2, 0x3e, 0x27, 0x03, 0x5c, 0x19, 0x57, + 0x52, 0x8a, 0xe5, 0xb5, 0xe2, 0x12, 0x11, 0xe7, 0xfa, 0x59, 0xbf, 0xb5, + 0xfd, 0x72, 0xda, 0xb1, 0x4f, 0x0b, 0xa4, 0xc1, 0xe8, 0x40, 0x32, 0xd4, + 0x1f, 0x42, 0xd9, 0xef, 0x4c, 0x26, 0x96, 0xef, 0xb4, 0x40, 0x56, 0x20, + 0xa0, 0x1c, 0x41, 0x29, 0xf3, 0xa0, 0xf2, 0xb2, 0x8d, 0xee, 0xeb, 0x25, + 0xf9, 0xb1, 0xe8, 0xae, 0x61, 0xd2, 0x40, 0xc3, 0xbb, 0x1f, 0xc3, 0x2b, + 0x29, 0x2b, 0x29, 0x89, 0x61, 0x09, 0x4b, 0x97, 0x90, 0xd7, 0xba, 0xd2, + 0x3c, 0x7b, 0x8a, 0x8f, 0xd8, 0x42, 0x50, 0x31, 0x97, 0xa5, 0x56, 0xb7, + 0x9b, 0xb6, 0x4b, 0x93, 0x4f, 0xd0, 0xd9, 0xd4, 0x34, 0xcf, 0x51, 0x48, + 0x9b, 0x6e, 0x0c, 0xfe, 0x0a, 0xba, 0x50, 0x7a, 0x0f, 0xda, 0x4c, 0x41, + 0x4e, 0x34, 0x04, 0xf3, 0x50, 0x02, 0x1f, 0xe3, 0x81, 0x9d, 0x4d, 0x92, + 0xe1, 0x44, 0x99, 0x63, 0x4c, 0x51, 0xbc, 0xef, 0x31, 0x04, 0x4d, 0x21, + 0xea, 0xad, 0x67, 0xd4, 0x09, 0x3a, 0x6b, 0x66, 0xec, 0x66, 0xb1, 0x5f, + 0x62, 0x83, 0x0e, 0x6a, 0xe5, 0x26, 0xef, 0x4e, 0xd4, 0x4a, 0x98, 0x66, + 0x1e, 0xec, 0x7e, 0x6a, 0x8b, 0x96, 0x3b, 0xf6, 0x47, 0x15, 0xd9, 0xa1, + 0xd2, 0x78, 0x18, 0xb2, 0x1d, 0xe1, 0x07, 0x8b, 0x61, 0xa2, 0x71, 0x2f, + 0xf3, 0xf6, 0x2c, 0x65, 0xfb, 0x61, 0x9f, 0x6f, 0xe7, 0xe1, 0x10, 0xef, + 0xb0, 0x25, 0x25, 0xcd, 0xf5, 0xcd, 0x52, 0x46, 0x25, 0xf9, 0xf9, 0xf4, + 0x24, 0x0b, 0x5e, 0x85, 0x0e, 0x5b, 0xb8, 0x44, 0x9f, 0xf9, 0x75, 0x0e, + 0xf9, 0xfa, 0xa7, 0x9d, 0x15, 0xc5, 0x86, 0xe6, 0x3d, 0x8b, 0x68, 0x08, + 0x19, 0x49, 0x42, 0xb8, 0xa2, 0x78, 0x32, 0xc8, 0xc5, 0x30, 0xc9, 0xa1, + 0xa4, 0x15, 0xb8, 0x94, 0x90, 0x66, 0x65, 0x8a, 0x51, 0x46, 0x27, 0xd5, + 0xf3, 0x7f, 0xb2, 0xcd, 0xc4, 0xaf, 0x58, 0x99, 0x79, 0xcb, 0xa7, 0x58, + 0x92, 0x1e, 0xf2, 0x85, 0x0e, 0xdf, 0x9a, 0xf4, 0x26, 0xcf, 0x35, 0x77, + 0xd9, 0x26, 0x24, 0x71, 0xee, 0xfd, 0x92, 0xda, 0xb9, 0xac, 0xd8, 0xd0, + 0x74, 0x27, 0x86, 0xc4, 0x79, 0x00, 0x73, 0xb6, 0x67, 0x6e, 0x8b, 0x1a, + 0x9f, 0x11, 0x6e, 0x51, 0x47, 0xb6, 0x59, 0x56, 0x1c, 0x03, 0xd4, 0x0b, + 0x19, 0xb5, 0x4c, 0x6c, 0x0e, 0x67, 0x96, 0x92, 0x59, 0x94, 0xb7, 0x83, + 0x98, 0x8f, 0x2d, 0x76, 0xf1, 0xb0, 0x11, 0x5e, 0xb0, 0xde, 0x1c, 0xfe, + 0xde, 0x0a, 0x98, 0x9c, 0xa2, 0xd1, 0xe8, 0x64, 0x6d, 0xfe, 0xde, 0x10, + 0xf9, 0x33, 0xf2, 0xcb, 0x74, 0xad, 0xce, 0x1a, 0x46, 0xcc, 0xe0, 0xef, + 0x41, 0x59, 0x84, 0xce, 0x79, 0x16, 0x6a, 0x9e, 0x39, 0x12, 0x63, 0xd4, + 0x47, 0x44, 0x23, 0xa5, 0x7c, 0x94, 0x4d, 0xc6, 0x4b, 0x09, 0xe1, 0x7c, + 0x6d, 0x94, 0x38, 0x16, 0x4d, 0x8b, 0xe5, 0x23, 0xc5, 0xd2, 0xb3, 0xa1, + 0x21, 0xb2, 0x77, 0xb5, 0x35, 0x29, 0x2c, 0x60, 0xcf, 0x62, 0x8a, 0xb8, + 0x20, 0x6e, 0x79, 0x9c, 0x43, 0x69, 0x5a, 0x90, 0x59, 0x99, 0x83, 0xf7, + 0x55, 0xb7, 0x46, 0x63, 0x56, 0x8e, 0x58, 0x2f, 0xd3, 0xfb, 0x43, 0x0c, + 0xd5, 0xa9, 0xa9, 0x3e, 0x2d, 0x06, 0xee, 0x1e, 0xf5, 0x83, 0x43, 0xe7, + 0x78, 0xd4, 0x15, 0x51, 0x5a, 0x2e, 0x55, 0x5a, 0x15, 0xae, 0x81, 0x20, + 0x9f, 0xb2, 0x76, 0x51, 0xfe, 0xb5, 0x7d, 0x08, 0x44, 0x06, 0x8c, 0x60, + 0xc3, 0x5a, 0x6e, 0x44, 0x89, 0xe3, 0x0c, 0xb6, 0x8c, 0xac, 0xb2, 0x49, + 0x5a, 0xcb, 0x98, 0xd1, 0x87, 0x52, 0x27, 0x7c, 0xa2, 0x52, 0xdb, 0x7c, + 0xd4, 0xc7, 0x4b, 0x7f, 0x57, 0x7c, 0xff, 0xf6, 0x04, 0xa7, 0x88, 0x29, + 0x78, 0x01, 0xee, 0xb6, 0xb9, 0x02, 0x69, 0x9e, 0x9d, 0xd8, 0xfe, 0x1f, + 0x2d, 0x6e, 0xe6, 0x53, 0xa4, 0xdc, 0x30, 0xc9, 0xb7, 0xd8, 0x0d, 0x3b, + 0xc0, 0xc9, 0xee, 0x7e, 0xb0, 0x98, 0x57, 0x5e, 0xf2, 0x12, 0x1f, 0xdb, + 0xc8, 0x74, 0x30, 0x6f, 0xb2, 0x0d, 0x86, 0xc6, 0x57, 0xbd, 0xcd, 0xd2, + 0x97, 0x9d, 0x02, 0x8c, 0x71, 0x73, 0xe2, 0x23, 0x12, 0x77, 0x22, 0xf5, + 0x4a, 0xbb, 0xf9, 0x74, 0x11, 0xe4, 0x50, 0xce, 0xcb, 0x78, 0x34, 0xed, + 0xbc, 0x91, 0x14, 0x39, 0xc1, 0xe3, 0x8f, 0x45, 0xb7, 0x0c, 0xb9, 0x81, + 0x8e, 0x02, 0x20, 0xcf, 0xfb, 0x7d, 0xb3, 0x34, 0xd0, 0xd9, 0x3b, 0xa2, + 0x4e, 0x98, 0x40, 0x62, 0xc0, 0x8d, 0x3c, 0x20, 0x6c, 0xa7, 0x9e, 0x93, + 0x42, 0x90, 0x56, 0x90, 0x96, 0xff, 0x3e, 0x7f, 0x9c, 0xe7, 0x66, 0x71, + 0x33, 0xc7, 0x28, 0x89, 0x4a, 0x8b, 0x44, 0x6d, 0xde, 0xe3, 0xff, 0x09, + 0x77, 0xfb, 0x2e, 0xe9, 0xcb, 0x13, 0x03, 0xaa, 0x57, 0xba, 0xa4, 0x52, + 0x0b, 0xdd, 0x26, 0xe4, 0x1a, 0x6e, 0xf8, 0xc1, 0xa1, 0x34, 0x2c, 0xc3, + 0xb3, 0x28, 0x13, 0x5b, 0x23, 0x44, 0x2b, 0x4f, 0x23, 0xf6, 0xac, 0x5c, + 0xe4, 0xd6, 0x32, 0x6f, 0xa9, 0xb7, 0x24, 0x1a, 0xfd, 0x35, 0xea, 0x20, + 0xf3, 0x28, 0x95, 0x69, 0x29, 0x20, 0x22, 0x1d, 0x41, 0xe0, 0xba, 0x44, + 0x94, 0x08, 0xa8, 0x7d, 0x14, 0x12, 0x2c, 0x04, 0xbf, 0x12, 0x8b, 0xfe, + 0x15, 0x6b, 0x9a, 0x8d, 0x34, 0x38, 0xa7, 0x97, 0xd5, 0xc3, 0x07, 0x54, + 0x66, 0x9d, 0x74, 0x4c, 0x16, 0x02, 0x69, 0x05, 0x64, 0x17, 0x09, 0x3d, + 0x0a, 0x0e, 0x5b, 0x01, 0x30, 0x41, 0x0f, 0x5e, 0x37, 0x41, 0x05, 0xcf, + 0x06, 0x53, 0x81, 0x52, 0x19, 0xf5, 0x2f, 0x47, 0x7d, 0x4e, 0x31, 0x6f, + 0x09, 0x6f, 0x72, 0xc1, 0x83, 0x87, 0xff, 0x62, 0xdb, 0x7e, 0x78, 0xc0, + 0x6e, 0x49, 0x9a, 0x92, 0xb4, 0xda, 0x6e, 0x4b, 0x5b, 0xcd, 0xfb, 0x8b, + 0xa7, 0xa5, 0x85, 0x0e, 0x4f, 0xe1, 0xf2, 0x7c, 0xe6, 0x57, 0xd9, 0xd0, + 0x13, 0xc5, 0xad, 0xd2, 0x27, 0x9d, 0xa8, 0x9f, 0xef, 0x19, 0x93, 0xcf, + 0x89, 0x4f, 0x60, 0xb9, 0xb5, 0x5e, 0x29, 0x37, 0xd2, 0xf4, 0x16, 0x6f, + 0x68, 0xca, 0x82, 0x37, 0x79, 0xd4, 0xeb, 0x9a, 0x7e, 0x28, 0x59, 0x4f, + 0x30, 0x7b, 0xdf, 0xcb, 0x80, 0xcc, 0x1f, 0xe2, 0x5b, 0xf8, 0x45, 0x7e, + 0x92, 0xe3, 0xa7, 0xe6, 0x03, 0x50, 0x6e, 0xa3, 0x7c, 0x1b, 0x72, 0x52, + 0xc2, 0x56, 0xff, 0x53, 0x2a, 0xf3, 0xf6, 0x93, 0x87, 0xcf, 0xdb, 0x52, + 0x92, 0x72, 0xd2, 0x36, 0xf1, 0x29, 0x69, 0x2f, 0x20, 0x55, 0x25, 0xfb, + 0xfc, 0xc5, 0xc2, 0xab, 0x4f, 0x14, 0x77, 0xab, 0xa4, 0xf0, 0x53, 0xad, + 0x3f, 0x9c, 0x8e, 0x6d, 0x87, 0x96, 0x71, 0x4a, 0x99, 0xcd, 0x9b, 0x52, + 0x76, 0x9c, 0x87, 0x1c, 0xae, 0x1b, 0x5c, 0x89, 0x40, 0xf7, 0xd2, 0xd4, + 0xcc, 0x2f, 0x95, 0xe8, 0x0c, 0x9a, 0x65, 0x4c, 0x6a, 0x0e, 0x77, 0xb6, + 0x4e, 0x00, 0xd6, 0x3c, 0x87, 0x85, 0x2f, 0xd4, 0xb4, 0x99, 0x44, 0xc8, + 0xc8, 0x61, 0xe8, 0x1d, 0xe3, 0x1b, 0x5e, 0x06, 0x5b, 0x8d, 0xb6, 0x66, + 0x70, 0x33, 0x9d, 0x43, 0xa4, 0x7d, 0x3e, 0x8b, 0x3c, 0x87, 0xce, 0x52, + 0x8d, 0x9f, 0x30, 0x59, 0x49, 0x81, 0xb8, 0x14, 0x3c, 0x6f, 0x48, 0x10, + 0x1d, 0xf6, 0x09, 0xa5, 0x45, 0x72, 0x42, 0xf6, 0xd8, 0xb3, 0x89, 0xe2, + 0x24, 0x70, 0xd8, 0xff, 0xe2, 0x9d, 0xe9, 0xdb, 0x53, 0x9c, 0x08, 0xe0, + 0xfc, 0x99, 0xc4, 0xbc, 0x43, 0x9a, 0xcc, 0x33, 0x2d, 0xca, 0x18, 0xf7, + 0xa3, 0x5e, 0xb9, 0xf8, 0x55, 0x6f, 0x92, 0xcf, 0xa5, 0xa5, 0x81, 0xa5, + 0x6b, 0x54, 0x26, 0x69, 0xcf, 0x5b, 0xcc, 0x37, 0x4f, 0x53, 0x12, 0xc5, + 0x72, 0x69, 0x4f, 0xf1, 0xa3, 0x73, 0x13, 0xb3, 0x53, 0xb1, 0x2f, 0x10, + 0x84, 0x3d, 0xde, 0x0e, 0x7b, 0x11, 0x1c, 0xf3, 0xa6, 0xfb, 0x9c, 0x3e, + 0x1a, 0x52, 0x9b, 0x44, 0x4e, 0x73, 0x37, 0xe7, 0x28, 0x95, 0x18, 0xc6, + 0x33, 0xde, 0x14, 0xdf, 0x2c, 0xe8, 0x52, 0xe9, 0x93, 0xfe, 0x78, 0x1a, + 0x6f, 0x8d, 0xb6, 0x11, 0x67, 0x1a, 0xd6, 0xab, 0xf9, 0xc7, 0xb1, 0x28, + 0x3b, 0x68, 0xd0, 0xb8, 0x1c, 0xd2, 0x40, 0xe9, 0x24, 0x6c, 0x07, 0x2f, + 0x0e, 0x7b, 0xd8, 0x8d, 0xe0, 0x48, 0xdc, 0x98, 0x3c, 0x31, 0x42, 0xe9, + 0x76, 0x52, 0x58, 0x29, 0x86, 0x5d, 0xb1, 0x28, 0x19, 0x82, 0x3d, 0x90, + 0x8d, 0xf2, 0x76, 0x48, 0x70, 0xda, 0xc1, 0x62, 0x7f, 0xdc, 0x7b, 0xcc, + 0xeb, 0xf2, 0xad, 0xf0, 0x63, 0x0b, 0xde, 0xf3, 0xaf, 0xfe, 0x8a, 0x8c, + 0x3d, 0x73, 0x48, 0xc1, 0x64, 0x3f, 0x4c, 0xe5, 0xc3, 0xe3, 0xca, 0x2e, + 0xf2, 0x33, 0xc4, 0x1b, 0x79, 0xde, 0x6e, 0x09, 0xdd, 0x22, 0xf3, 0x32, + 0xb5, 0x0f, 0x4e, 0x57, 0x06, 0xa7, 0xfa, 0xde, 0x55, 0x57, 0xf9, 0x55, + 0x95, 0xfa, 0x26, 0x3c, 0x33, 0x48, 0x26, 0x92, 0xd0, 0x64, 0xff, 0x4a, + 0xbf, 0xe0, 0xfe, 0x50, 0x4d, 0x2c, 0xeb, 0xe0, 0x13, 0xcb, 0x0a, 0xe5, + 0x0f, 0xf8, 0x10, 0x9c, 0xe3, 0x97, 0x04, 0x62, 0xd1, 0x43, 0x83, 0x95, + 0xc4, 0x12, 0x9a, 0x68, 0x4f, 0x97, 0xff, 0xa2, 0xd3, 0x40, 0x02, 0x1b, + 0xaf, 0xa3, 0x3f, 0x0e, 0xc4, 0x62, 0x6f, 0x6b, 0xeb, 0x88, 0x63, 0xb7, + 0xd2, 0x75, 0x7c, 0x29, 0xc0, 0x3d, 0x67, 0x04, 0xcd, 0x26, 0x6e, 0x03, + 0xd9, 0x01, 0x7b, 0x48, 0x4b, 0x21, 0x18, 0x9e, 0xa3, 0x36, 0x71, 0x99, + 0x06, 0x76, 0x07, 0xd3, 0xcc, 0x86, 0xf2, 0x03, 0x85, 0x01, 0xc3, 0x5e, + 0xb3, 0x9d, 0x6b, 0xf2, 0x92, 0x7a, 0xc7, 0x1c, 0xde, 0x6c, 0x80, 0x1c, + 0x53, 0x37, 0x69, 0x9a, 0xc7, 0xd3, 0x99, 0xd7, 0xbe, 0xe8, 0xb9, 0x3e, + 0xda, 0xe2, 0xd9, 0xa6, 0x44, 0xfb, 0x45, 0x6d, 0x9f, 0xde, 0xb8, 0x6c, + 0xc3, 0x59, 0xf3, 0x6d, 0x1d, 0x30, 0x91, 0x17, 0x14, 0xbf, 0x42, 0xad, + 0x4d, 0x1a, 0x4a, 0xc1, 0x65, 0x28, 0x23, 0xb3, 0x91, 0x3b, 0xf7, 0x51, + 0x1d, 0xfa, 0x82, 0x3e, 0x7f, 0x7c, 0x79, 0xee, 0xb8, 0x46, 0x5b, 0xb1, + 0x46, 0x66, 0xa6, 0x06, 0x4a, 0x47, 0x91, 0xfc, 0x7a, 0xa4, 0xcd, 0x10, + 0xcc, 0xe1, 0x3f, 0xe0, 0x5b, 0xa5, 0xe4, 0xce, 0x34, 0x18, 0x55, 0x00, + 0x28, 0x0b, 0xb3, 0x9d, 0x21, 0xfb, 0x28, 0x6c, 0xc7, 0x2d, 0x48, 0x4d, + 0x5e, 0xdb, 0x16, 0xbc, 0xae, 0x69, 0xf7, 0xbe, 0xe5, 0xfd, 0xfd, 0x5f, + 0x55, 0x73, 0x47, 0x54, 0xc5, 0x06, 0x18, 0xb0, 0xb6, 0xa5, 0x4d, 0x2f, + 0x1b, 0xd5, 0x28, 0xa5, 0x76, 0x25, 0x75, 0x4f, 0xd0, 0xf7, 0xe1, 0x9b, + 0xc2, 0x4d, 0xf0, 0xc4, 0x12, 0x27, 0xbc, 0xea, 0xdd, 0x82, 0x7a, 0x0c, + 0x52, 0x43, 0x84, 0x8e, 0x95, 0x04, 0xa9, 0x15, 0x30, 0xc1, 0xda, 0xce, + 0x42, 0x54, 0x8d, 0xb7, 0xf5, 0xaf, 0x90, 0xf6, 0x2f, 0x22, 0xb5, 0xff, + 0x50, 0x79, 0xec, 0x90, 0x09, 0xb9, 0x21, 0xbb, 0x93, 0xea, 0xc2, 0xb3, + 0x3b, 0x1b, 0xc4, 0xc7, 0xeb, 0xe3, 0xa3, 0x62, 0x96, 0x80, 0xa8, 0xc8, + 0x81, 0x72, 0x3b, 0x13, 0x64, 0x45, 0x9f, 0xaf, 0x3b, 0xe5, 0x3c, 0x8f, + 0xfc, 0x49, 0x1b, 0x17, 0x5b, 0x6d, 0x3d, 0xa8, 0x8d, 0x32, 0xdd, 0x69, + 0x98, 0x7e, 0x8a, 0xce, 0xec, 0x0d, 0x44, 0xef, 0xbe, 0x64, 0xcc, 0xb0, + 0x44, 0xa8, 0xc5, 0xb8, 0x91, 0x23, 0xee, 0x74, 0x74, 0x85, 0x69, 0x76, + 0x06, 0xfa, 0xa2, 0x03, 0x83, 0xad, 0xf5, 0x69, 0x57, 0x46, 0xc5, 0x98, + 0x50, 0x96, 0xff, 0x22, 0x9f, 0x25, 0x57, 0xf9, 0xc9, 0xde, 0xf3, 0xf6, + 0x03, 0x32, 0x95, 0xbf, 0xe1, 0x34, 0xd9, 0x3b, 0x1d, 0xd8, 0x26, 0x41, + 0x21, 0xbd, 0x67, 0xfa, 0x5a, 0x15, 0x10, 0x42, 0xda, 0xb8, 0xd8, 0x5e, + 0x5b, 0x96, 0x7c, 0x46, 0xa5, 0xf6, 0x41, 0xa0, 0xb7, 0x61, 0xc0, 0x98, + 0xd1, 0x83, 0x5c, 0xc1, 0x19, 0x18, 0x8e, 0xbe, 0x36, 0xf8, 0x3a, 0x96, + 0x29, 0x1d, 0x4f, 0xba, 0x3a, 0x2e, 0x4a, 0x3d, 0x8f, 0x55, 0x85, 0x53, + 0xa9, 0xfd, 0x2f, 0xe4, 0xc0, 0x44, 0x1b, 0xf9, 0x9b, 0x12, 0x7e, 0x5a, + 0xd9, 0x2b, 0x95, 0x62, 0xbe, 0xf6, 0x6b, 0xf9, 0x9a, 0x13, 0x66, 0x05, + 0x27, 0xe6, 0xac, 0xdc, 0xce, 0x05, 0x2b, 0x02, 0xf1, 0x7c, 0x71, 0x21, + 0x72, 0x5d, 0xbe, 0x8a, 0x31, 0x5f, 0x4c, 0xe3, 0x40, 0xf4, 0xd3, 0x3e, + 0x63, 0xc6, 0x58, 0xcc, 0x17, 0xea, 0x89, 0x42, 0x7c, 0xc4, 0x2f, 0x9e, + 0x33, 0x10, 0x8f, 0xc8, 0xdf, 0x95, 0xf3, 0x51, 0x57, 0x70, 0x28, 0xa8, + 0xf7, 0x68, 0xa3, 0x8d, 0x6c, 0xc8, 0x8c, 0x5a, 0xc3, 0xef, 0x54, 0x4e, + 0xcb, 0xf1, 0x23, 0x98, 0x63, 0xfe, 0x4a, 0x8e, 0xb9, 0xff, 0x30, 0xc7, + 0x06, 0x2d, 0xc7, 0x7e, 0xcc, 0x31, 0x69, 0xbe, 0x9c, 0xe3, 0x23, 0x4a, + 0x96, 0x1c, 0xb2, 0x1f, 0x91, 0xff, 0x84, 0x52, 0x6f, 0xad, 0x4c, 0xdb, + 0x5a, 0x2e, 0xa6, 0x06, 0x7a, 0xad, 0x98, 0xff, 0xd3, 0x11, 0x67, 0x80, + 0x69, 0x1c, 0x8e, 0x16, 0x0f, 0xbe, 0x78, 0x25, 0xff, 0x3f, 0x39, 0xc4, + 0x36, 0xa4, 0xc3, 0xf6, 0xfa, 0x14, 0x18, 0x0b, 0x0e, 0xe3, 0x28, 0x6d, + 0x34, 0xf8, 0x86, 0x88, 0xd7, 0x39, 0x10, 0xad, 0xef, 0x2b, 0x94, 0x0b, + 0xfd, 0x90, 0x6d, 0xd0, 0xc6, 0x2c, 0x49, 0x61, 0xaa, 0xec, 0xa4, 0x36, + 0x25, 0xc4, 0xef, 0xfa, 0x41, 0x34, 0xbf, 0x80, 0xb4, 0xe4, 0x59, 0xb9, + 0xd1, 0xea, 0x39, 0xb8, 0xd1, 0xb4, 0xab, 0x00, 0xc4, 0x5a, 0x3a, 0xdf, + 0x93, 0x99, 0x57, 0x12, 0x69, 0x75, 0x18, 0x82, 0xbf, 0x94, 0x92, 0xc2, + 0xd3, 0x51, 0xbb, 0xa2, 0xa3, 0x85, 0x7f, 0xa5, 0x36, 0x29, 0x22, 0x7f, + 0xea, 0x59, 0x11, 0x30, 0x68, 0xeb, 0x2c, 0x56, 0xfa, 0x45, 0xcd, 0x6a, + 0xd0, 0x6b, 0x3d, 0x04, 0xfb, 0xb9, 0xc5, 0xd2, 0x0a, 0x99, 0x7b, 0xee, + 0xae, 0xe9, 0x8b, 0x79, 0x52, 0x90, 0x27, 0x9f, 0x93, 0x0f, 0xca, 0xa9, + 0x35, 0x07, 0xab, 0xaa, 0x16, 0x1a, 0xe8, 0xfa, 0xda, 0x5a, 0xe8, 0x6d, + 0x8d, 0x2d, 0x4b, 0x87, 0xec, 0x09, 0x91, 0x1c, 0xe5, 0x4d, 0x23, 0x77, + 0xea, 0x4e, 0x91, 0x7b, 0xd6, 0xc1, 0x0b, 0x02, 0x5f, 0x93, 0x68, 0xba, + 0x7c, 0x95, 0x87, 0x57, 0x62, 0x6d, 0x6e, 0xde, 0x98, 0x70, 0x82, 0xd3, + 0x55, 0x2b, 0xa7, 0xd3, 0xbd, 0x68, 0xe3, 0x3a, 0xcf, 0x29, 0x1c, 0x94, + 0xf9, 0x42, 0xfc, 0x39, 0xf9, 0x82, 0x4a, 0x0a, 0x7e, 0x8e, 0xda, 0x7d, + 0x9d, 0x63, 0xab, 0x37, 0x47, 0x49, 0x83, 0x44, 0x5f, 0x9e, 0xfc, 0xb6, + 0x6a, 0x0a, 0xf1, 0xe3, 0x51, 0xef, 0xc4, 0x3a, 0xbf, 0xbf, 0x2b, 0x31, + 0x98, 0x86, 0xe9, 0x9f, 0x9a, 0x97, 0x10, 0xa9, 0xc0, 0x70, 0x1e, 0x88, + 0x98, 0x42, 0x4c, 0x81, 0x9d, 0x3e, 0xdd, 0x09, 0x79, 0x77, 0x77, 0x59, + 0x82, 0xd2, 0x42, 0x56, 0x4f, 0x0d, 0x5d, 0xbf, 0x6f, 0x0c, 0x7b, 0xb5, + 0xb0, 0x72, 0x15, 0x52, 0x90, 0x8a, 0x61, 0xd5, 0xb9, 0xf2, 0x94, 0x54, + 0x94, 0x5a, 0x9c, 0xb5, 0xab, 0x72, 0x0c, 0x91, 0xa0, 0x8f, 0x5a, 0x02, + 0x4f, 0xf5, 0xd1, 0xdc, 0x78, 0xaf, 0x3c, 0x51, 0xb4, 0x27, 0xaf, 0x4e, + 0x8f, 0x4d, 0x8f, 0x3f, 0x11, 0x6b, 0xbf, 0x83, 0xa5, 0xb5, 0x1e, 0x4b, + 0x81, 0x14, 0x88, 0xb5, 0x2b, 0xf2, 0x0c, 0x91, 0x3a, 0x31, 0x57, 0x71, + 0xe8, 0xdf, 0x39, 0x6b, 0x8d, 0xae, 0xac, 0x92, 0xe5, 0xe9, 0x39, 0x1b, + 0xa1, 0x57, 0xc4, 0x18, 0x67, 0x86, 0x27, 0x96, 0x41, 0x9e, 0x2b, 0x62, + 0x72, 0x99, 0x42, 0x26, 0x4f, 0xd0, 0x67, 0xf6, 0x98, 0x82, 0x2b, 0x03, + 0x54, 0xa3, 0x5f, 0xe9, 0x9f, 0xa3, 0x96, 0x4b, 0xe7, 0x64, 0x46, 0xa4, + 0xb9, 0x0a, 0x61, 0x2e, 0xcb, 0xa5, 0xa7, 0x55, 0x10, 0x13, 0x9c, 0xa4, + 0xc0, 0x12, 0xbc, 0x5c, 0x1a, 0x7b, 0x3b, 0x57, 0xea, 0xa5, 0xb1, 0x12, + 0x4b, 0xc3, 0x74, 0x10, 0x82, 0xb3, 0xb0, 0x27, 0xb2, 0x96, 0xb1, 0xd8, + 0x46, 0xfd, 0xfd, 0x74, 0x5c, 0x9f, 0x78, 0xde, 0x8d, 0x1c, 0xa9, 0x4f, + 0x6e, 0x2c, 0x37, 0xc2, 0xc9, 0x24, 0x95, 0x8e, 0xa7, 0x5b, 0xae, 0xbc, + 0x67, 0xd4, 0xde, 0x4b, 0x18, 0xfa, 0x4c, 0x2d, 0x34, 0x10, 0xeb, 0x2d, + 0x08, 0x09, 0x91, 0xd9, 0x0a, 0xd6, 0x96, 0xcf, 0xc0, 0x1a, 0x54, 0xac, + 0x6d, 0xa4, 0x28, 0x28, 0xa3, 0x26, 0x7c, 0x66, 0x57, 0xa0, 0x55, 0x32, + 0x75, 0x25, 0xe4, 0x18, 0x90, 0x8a, 0x96, 0xa4, 0x5b, 0x65, 0x5b, 0x8d, + 0x19, 0xb0, 0x3f, 0xeb, 0x7d, 0x6a, 0x80, 0xc0, 0x25, 0x55, 0xdb, 0x81, + 0x5b, 0x1d, 0xf7, 0x48, 0x1b, 0xe2, 0x12, 0x4f, 0xfe, 0xd9, 0xf6, 0x0a, + 0x4a, 0xf5, 0xce, 0xda, 0x5c, 0xcd, 0xe7, 0x5c, 0x57, 0x8c, 0x14, 0xf8, + 0xd2, 0xbf, 0x8a, 0x24, 0xf7, 0x1c, 0x35, 0x1f, 0x05, 0xfa, 0x8c, 0xfa, + 0x08, 0x33, 0xf7, 0xd0, 0xa7, 0xcc, 0x5b, 0xd0, 0xfb, 0xf3, 0x41, 0x5f, + 0xfa, 0x05, 0xcd, 0x4a, 0x4d, 0x5f, 0xdc, 0x6b, 0x6d, 0x43, 0x83, 0xa2, + 0xf9, 0xb6, 0xcd, 0x66, 0x22, 0x8b, 0x64, 0xcd, 0xb3, 0x55, 0x75, 0x88, + 0x73, 0x9e, 0x1a, 0xa7, 0x40, 0x56, 0x91, 0xc2, 0x04, 0xbf, 0x8b, 0x52, + 0x71, 0xc8, 0xcc, 0x22, 0x5d, 0xed, 0x95, 0x12, 0xbb, 0x58, 0x11, 0x1a, + 0xcd, 0x37, 0x35, 0xfa, 0x5a, 0x15, 0xde, 0xbe, 0x4f, 0x3e, 0x1f, 0xa1, + 0x7e, 0xe0, 0x2a, 0xe4, 0x0f, 0x54, 0xa6, 0xe9, 0x45, 0x38, 0xae, 0xd9, + 0x1b, 0x80, 0xde, 0x7f, 0xc6, 0x18, 0xfe, 0x1e, 0x26, 0x37, 0x7e, 0xa4, + 0x12, 0xa4, 0x90, 0x07, 0x07, 0xfe, 0xaa, 0x52, 0xda, 0xa0, 0x52, 0x69, + 0x3a, 0xf6, 0x6f, 0x57, 0x67, 0xf6, 0xfa, 0xa3, 0xe3, 0x86, 0x5b, 0xca, + 0xf6, 0x4a, 0xe3, 0x23, 0xff, 0xac, 0xbc, 0xa8, 0xcd, 0x06, 0xbf, 0xa8, + 0xcd, 0x06, 0xbb, 0x61, 0x89, 0x1b, 0x7a, 0xd7, 0x0e, 0xbd, 0x58, 0xef, + 0x30, 0x31, 0xa7, 0x3c, 0x01, 0xea, 0x39, 0x36, 0x5f, 0xeb, 0x79, 0x5a, + 0x06, 0x50, 0x63, 0x0d, 0xd3, 0x77, 0x93, 0x4f, 0xd1, 0x1c, 0x50, 0x2a, + 0x7a, 0x12, 0x43, 0x20, 0x91, 0xdf, 0x28, 0xdd, 0xea, 0x13, 0x78, 0x76, + 0x26, 0x32, 0xac, 0x74, 0xaa, 0x34, 0x9c, 0xbf, 0xe9, 0xe1, 0x2c, 0x1e, + 0xfa, 0x54, 0xbd, 0x9e, 0xca, 0xd8, 0x3d, 0x97, 0xa9, 0x6c, 0x41, 0x84, + 0xda, 0xaf, 0xa3, 0x7d, 0xc7, 0x1e, 0x2c, 0x43, 0x43, 0x88, 0xc6, 0xc3, + 0x36, 0x53, 0x0b, 0x9c, 0x94, 0xd6, 0xc2, 0x5f, 0xa3, 0xb5, 0xd7, 0xff, + 0x13, 0x5a, 0x33, 0xb8, 0xb0, 0xe5, 0x96, 0x40, 0xef, 0xdf, 0x86, 0xfe, + 0xab, 0x94, 0x36, 0x76, 0x04, 0xa5, 0xf1, 0xd7, 0x51, 0xda, 0x0b, 0xea, + 0x3d, 0x65, 0x39, 0x4a, 0x87, 0x9d, 0x5a, 0x77, 0x4c, 0xf4, 0xa5, 0xc1, + 0xb5, 0xb4, 0xf6, 0xc0, 0x75, 0xb4, 0x26, 0x5f, 0x43, 0x6b, 0xdf, 0x46, + 0x5a, 0x63, 0x31, 0x35, 0xa5, 0x25, 0xd4, 0x2b, 0x1b, 0xca, 0xe2, 0xe1, + 0xf9, 0x65, 0xb9, 0x18, 0x96, 0x17, 0xc3, 0x8a, 0x53, 0xc6, 0x7f, 0x07, + 0xad, 0x55, 0xa4, 0x1b, 0x5d, 0x53, 0x4b, 0xd8, 0x20, 0xa5, 0xb6, 0x55, + 0x18, 0xeb, 0x9c, 0x70, 0xde, 0x7f, 0x48, 0x6d, 0x37, 0x8f, 0xa0, 0xb6, + 0x66, 0x8d, 0xda, 0x0e, 0x7c, 0x8d, 0xda, 0x5a, 0xbe, 0x46, 0x6d, 0xd3, + 0x81, 0xf2, 0xb9, 0x71, 0x65, 0x03, 0xd1, 0xe7, 0xfb, 0x2e, 0x53, 0xdb, + 0xd7, 0x5b, 0xce, 0x3d, 0x83, 0x2f, 0xd6, 0x23, 0xfd, 0x9d, 0x3a, 0xff, + 0x71, 0x72, 0xe3, 0xf9, 0x8f, 0xaf, 0x7e, 0x67, 0xc1, 0xef, 0xca, 0x06, + 0xde, 0xbf, 0x6e, 0xde, 0xf7, 0x7a, 0x5a, 0x7c, 0xf3, 0x6f, 0x60, 0xbd, + 0xbc, 0x56, 0xfe, 0xab, 0xe8, 0xc4, 0x81, 0xcb, 0x6b, 0xe5, 0x5b, 0xf4, + 0x55, 0xf0, 0x23, 0xc7, 0x72, 0xa0, 0xf7, 0xde, 0xc1, 0x6f, 0x5e, 0x4b, + 0x8e, 0x9c, 0x30, 0x83, 0x69, 0x30, 0xec, 0x34, 0x46, 0x46, 0x41, 0x7f, + 0xb4, 0x7e, 0xc8, 0x84, 0xf1, 0x6b, 0x1a, 0x42, 0x63, 0x7f, 0x74, 0x67, + 0xcc, 0x10, 0x4a, 0xf4, 0x8c, 0xcd, 0x33, 0x6b, 0x56, 0x4f, 0x49, 0xd0, + 0x78, 0x8a, 0x72, 0x36, 0x98, 0x94, 0x2a, 0xff, 0x55, 0xb5, 0x8a, 0x94, + 0x5f, 0xd2, 0x79, 0x9d, 0x0b, 0x27, 0x44, 0x30, 0x17, 0x3d, 0xa0, 0x70, + 0xd8, 0x77, 0x50, 0xdb, 0xc3, 0x24, 0xc4, 0xee, 0x44, 0xed, 0xf8, 0xac, + 0xf2, 0x1e, 0x17, 0xfa, 0x75, 0x49, 0x88, 0x7f, 0x44, 0xd9, 0x55, 0x7c, + 0xaf, 0xb2, 0x67, 0x9e, 0x31, 0x4c, 0x32, 0x47, 0xc1, 0x73, 0xbe, 0x7b, + 0xf8, 0x52, 0x25, 0x47, 0x9a, 0x14, 0xa1, 0x5e, 0xd1, 0xd9, 0xa6, 0x1f, + 0xf2, 0xa4, 0x69, 0xcf, 0x3c, 0x3e, 0x62, 0xcd, 0xff, 0x85, 0x34, 0xe1, + 0x2c, 0x69, 0xa2, 0x2b, 0xcc, 0x2b, 0xe6, 0x6e, 0x95, 0xed, 0x40, 0xc4, + 0x8d, 0xf6, 0x0c, 0xdf, 0xb7, 0x65, 0x17, 0x98, 0x67, 0x7d, 0x4b, 0x61, + 0x1a, 0x13, 0x75, 0x0b, 0x99, 0xfd, 0xd1, 0x85, 0xb1, 0x49, 0x70, 0x50, + 0xfd, 0x85, 0x64, 0x3a, 0x7b, 0x46, 0x09, 0x29, 0x67, 0xe4, 0xa0, 0xcc, + 0xb5, 0x6c, 0xee, 0x01, 0x57, 0x2a, 0x5c, 0x32, 0xc1, 0xa9, 0xf7, 0x7b, + 0x9c, 0x60, 0x9e, 0x99, 0xac, 0x70, 0x4d, 0xb7, 0x3b, 0x58, 0xe7, 0x1a, + 0xe5, 0x47, 0x18, 0xcb, 0x66, 0x9e, 0xd2, 0xc4, 0xbe, 0x9e, 0x77, 0x6d, + 0x7b, 0xe6, 0x95, 0x46, 0x48, 0xc8, 0x4a, 0x3d, 0xcb, 0x76, 0x37, 0xf6, + 0x3c, 0xaf, 0x9c, 0x53, 0xa6, 0xc1, 0x09, 0xb9, 0x59, 0x4e, 0x00, 0x6e, + 0x96, 0xf9, 0xa6, 0x89, 0xb9, 0x33, 0x3a, 0x8b, 0x20, 0x35, 0xd7, 0x7c, + 0x5a, 0x54, 0x0e, 0xca, 0x15, 0xca, 0x39, 0xd9, 0x91, 0x6b, 0xef, 0xcc, + 0x03, 0x73, 0x81, 0xd5, 0xe3, 0x52, 0xec, 0xf2, 0x32, 0xe5, 0x5e, 0x79, + 0xbf, 0xd2, 0x8c, 0xfc, 0xf8, 0x33, 0xbe, 0xae, 0x8c, 0x1e, 0x2f, 0x62, + 0xbb, 0xa7, 0xa9, 0x5c, 0xa1, 0xa4, 0x7a, 0x49, 0x73, 0xaa, 0x6f, 0xa5, + 0x4c, 0x4b, 0x6e, 0x68, 0xb8, 0x5c, 0x6d, 0x55, 0xf2, 0xfc, 0x1f, 0x28, + 0x2b, 0xfd, 0x13, 0x73, 0xd9, 0x70, 0x1e, 0x58, 0x0b, 0x78, 0x4f, 0xb7, + 0x2a, 0x06, 0x0e, 0xfa, 0xf3, 0x60, 0x59, 0x40, 0xf0, 0x7c, 0xe6, 0xe7, + 0x0b, 0x4e, 0x69, 0x1e, 0xaf, 0xa0, 0xf7, 0x3b, 0x83, 0xef, 0xaa, 0xa4, + 0xf9, 0xb0, 0xb4, 0xe8, 0x6c, 0x36, 0xd0, 0x1c, 0x99, 0xdd, 0x34, 0x4f, + 0x34, 0x6d, 0x34, 0x65, 0x6c, 0x33, 0xb5, 0xe6, 0x7c, 0x4b, 0x67, 0x6a, + 0xae, 0x69, 0x44, 0xaa, 0x26, 0x76, 0x9a, 0x0b, 0xcc, 0x6e, 0x51, 0x61, + 0xf1, 0xda, 0x27, 0xb7, 0x2a, 0x5b, 0x31, 0x2d, 0x8a, 0x72, 0x01, 0x53, + 0xf3, 0xbc, 0x8d, 0xf7, 0xa6, 0x4c, 0x86, 0xce, 0xe7, 0x7b, 0x48, 0x13, + 0xd9, 0x1b, 0xe0, 0xdd, 0xbe, 0x74, 0x9f, 0x22, 0xdf, 0x26, 0x2f, 0x52, + 0xcc, 0xf9, 0x74, 0xde, 0x99, 0x4a, 0x03, 0xb7, 0xf6, 0x31, 0x8d, 0xe6, + 0x19, 0xfd, 0xd1, 0xe7, 0x86, 0xa7, 0x81, 0xf1, 0x9a, 0x94, 0x66, 0xd3, + 0x94, 0xba, 0xa9, 0x67, 0x4a, 0x31, 0x20, 0xb8, 0x0f, 0xfa, 0x2b, 0x02, + 0x7c, 0xc1, 0x39, 0xff, 0x1f, 0x54, 0x6a, 0x1f, 0x37, 0x6b, 0xf0, 0x2d, + 0xd4, 0xc8, 0x8e, 0x48, 0xf9, 0x98, 0x4e, 0x9a, 0x3a, 0xb3, 0xfb, 0x6a, + 0xfa, 0xc4, 0xeb, 0xd2, 0x67, 0xf9, 0x5a, 0xfa, 0x6e, 0x81, 0x17, 0xbe, + 0x21, 0xa6, 0xf3, 0xd7, 0xc5, 0xf4, 0x91, 0x16, 0xd3, 0x17, 0x03, 0xaa, + 0x6a, 0x68, 0xa2, 0x25, 0xe9, 0x1d, 0x34, 0x65, 0x50, 0x4b, 0x4c, 0x22, + 0x10, 0x97, 0xb9, 0x88, 0xda, 0xf6, 0xe4, 0x9a, 0x4f, 0xf0, 0x0c, 0xb6, + 0x89, 0xa0, 0x64, 0x88, 0xdc, 0xaf, 0xb0, 0xe2, 0x5e, 0x1f, 0x1b, 0xba, + 0xc8, 0x0f, 0x7d, 0x1c, 0x4f, 0x47, 0x4e, 0x27, 0x5d, 0x99, 0x15, 0xaf, + 0xc1, 0x78, 0xdc, 0x8e, 0xdc, 0x64, 0xbc, 0x67, 0xce, 0x37, 0x7b, 0x12, + 0xb0, 0x06, 0x17, 0x60, 0x0d, 0x3e, 0x8e, 0x35, 0xe8, 0x44, 0x09, 0x69, + 0x28, 0x7a, 0x24, 0x36, 0x49, 0xa5, 0x69, 0xfb, 0x40, 0x39, 0x26, 0xd3, + 0x34, 0xb1, 0x60, 0xcd, 0xb7, 0x7a, 0x3e, 0xc3, 0x7a, 0xe2, 0xf3, 0x59, + 0x3f, 0x8b, 0x35, 0xc5, 0x7b, 0x24, 0xff, 0xfb, 0x5a, 0x9a, 0x9e, 0x19, + 0xf8, 0x50, 0x65, 0xf7, 0x1e, 0xff, 0xd8, 0xe8, 0xab, 0x96, 0xbf, 0xa5, + 0xd0, 0x96, 0x78, 0x9f, 0x36, 0xef, 0x0e, 0x02, 0x29, 0xd5, 0x6c, 0xe5, + 0x43, 0xdf, 0x66, 0xa6, 0x36, 0xb1, 0x96, 0xfa, 0x7d, 0x21, 0x6e, 0x92, + 0xdf, 0x2c, 0x45, 0xc3, 0x61, 0x7b, 0x8d, 0x66, 0x9b, 0xc5, 0x4a, 0x2d, + 0x4f, 0x4f, 0x24, 0xb3, 0xf2, 0x96, 0x9a, 0x97, 0x6e, 0x45, 0x2e, 0xb0, + 0x0b, 0xc1, 0xdb, 0xdd, 0xed, 0xa4, 0x80, 0xee, 0x9a, 0xa1, 0x9c, 0x52, + 0x5b, 0x83, 0x0d, 0x23, 0x79, 0x4e, 0x77, 0x7f, 0x4e, 0xd9, 0x1e, 0xa9, + 0x80, 0xae, 0x40, 0x0a, 0xb4, 0xca, 0xad, 0xc8, 0x63, 0x0a, 0x4f, 0x51, + 0xdf, 0xa2, 0x33, 0xc2, 0x97, 0xad, 0xb1, 0x44, 0x0f, 0x5f, 0x3c, 0x6c, + 0x97, 0x6e, 0x0c, 0x8b, 0x8a, 0x2b, 0xd0, 0x68, 0xaf, 0x08, 0x6c, 0x95, + 0x0c, 0x67, 0xe9, 0x3a, 0xa3, 0xa1, 0xe8, 0xc1, 0x61, 0xc8, 0x9e, 0x14, + 0x41, 0x19, 0xd1, 0x4d, 0x8a, 0xa8, 0x8c, 0x78, 0x6f, 0xba, 0x4b, 0x9e, + 0x50, 0x43, 0xdf, 0xe0, 0xc2, 0xad, 0xf5, 0x5d, 0x26, 0xd3, 0xa9, 0x84, + 0xa9, 0x74, 0xbe, 0x9d, 0xbe, 0xbb, 0x1b, 0xdf, 0x1d, 0x15, 0x71, 0x43, + 0x5f, 0xfb, 0x0d, 0xfa, 0xda, 0x93, 0xd7, 0xd4, 0x24, 0x3c, 0x3b, 0x16, + 0xf9, 0xab, 0xf2, 0xaa, 0xbe, 0x6e, 0x69, 0x46, 0x1f, 0x64, 0x1f, 0x0b, + 0xd3, 0x95, 0x4a, 0x9f, 0xa9, 0x71, 0xfb, 0x2f, 0x06, 0xcd, 0xfe, 0xcb, + 0xab, 0xd7, 0xf5, 0x51, 0xd4, 0x86, 0x4b, 0x7c, 0xbc, 0xf9, 0xab, 0x68, + 0x57, 0x5f, 0xbc, 0x3f, 0xda, 0xa1, 0x59, 0x1e, 0x61, 0x6e, 0xeb, 0xd1, + 0xc6, 0x8b, 0xad, 0xda, 0x78, 0x31, 0xd6, 0x47, 0x86, 0x21, 0x1c, 0xcb, + 0xe5, 0x4e, 0x3f, 0xee, 0x22, 0x82, 0x5d, 0xf6, 0x4a, 0x35, 0xf3, 0x89, + 0x90, 0x50, 0x33, 0x40, 0xf5, 0x1e, 0xcd, 0xcf, 0xfb, 0x57, 0xd1, 0x23, + 0x7d, 0x86, 0x8c, 0xab, 0xa5, 0xf1, 0xed, 0x7e, 0xba, 0x1e, 0x2b, 0x85, + 0xae, 0xad, 0xc1, 0xdc, 0x07, 0x0f, 0x8f, 0x32, 0x4d, 0x39, 0x79, 0xda, + 0x38, 0xea, 0xa4, 0x05, 0xf5, 0x07, 0x8f, 0x7c, 0x93, 0x87, 0xa6, 0x8a, + 0x5a, 0x4f, 0xc9, 0xd1, 0xf3, 0x70, 0x4e, 0x9d, 0x84, 0x67, 0x9f, 0x60, + 0x1e, 0x3e, 0x56, 0xcb, 0x4d, 0xa9, 0xa7, 0xae, 0x5d, 0x53, 0x45, 0x57, + 0xb3, 0xb4, 0x0f, 0xd3, 0x35, 0x55, 0x13, 0xf5, 0x99, 0x71, 0x3c, 0x97, + 0xc5, 0x80, 0x28, 0x9b, 0xf5, 0x59, 0x7a, 0x5a, 0xd2, 0x89, 0x91, 0x7d, + 0x4e, 0x3a, 0x73, 0x5e, 0x0f, 0x3b, 0xb5, 0x5d, 0xe5, 0x74, 0x7d, 0xa2, + 0x5b, 0x5b, 0x8b, 0x44, 0xd7, 0xf7, 0x60, 0xba, 0xa1, 0xe9, 0x30, 0xe3, + 0x65, 0xa5, 0x94, 0x30, 0xb8, 0xf6, 0xcb, 0xcb, 0x02, 0x8b, 0xa5, 0xfd, + 0x7e, 0x10, 0x5c, 0x81, 0x47, 0xa4, 0x97, 0x23, 0x09, 0xc6, 0x97, 0x4e, + 0x79, 0x5d, 0x34, 0x24, 0x52, 0xf8, 0xa2, 0xba, 0xcd, 0x04, 0x27, 0x97, + 0x05, 0xf6, 0x6b, 0xf6, 0xb1, 0x47, 0x96, 0x17, 0x95, 0x6b, 0x6e, 0x00, + 0x6a, 0x1d, 0x6c, 0x38, 0x2a, 0x0e, 0x72, 0x40, 0xb2, 0x6d, 0x91, 0x75, + 0x19, 0xc3, 0x79, 0x63, 0x3b, 0x99, 0x83, 0x19, 0x0f, 0xc1, 0xa4, 0x67, + 0x24, 0x21, 0xcc, 0x1e, 0x3c, 0xbd, 0xf4, 0xa0, 0x42, 0x8a, 0x0e, 0x6a, + 0x12, 0xd7, 0xf3, 0x81, 0xa0, 0x64, 0x43, 0x89, 0x6b, 0x5c, 0x38, 0x0f, + 0x6b, 0x35, 0x17, 0x25, 0x2e, 0x72, 0xd3, 0x39, 0x35, 0x8f, 0xda, 0xef, + 0x6c, 0x94, 0x3d, 0xec, 0x73, 0xd0, 0xdb, 0xad, 0x59, 0x2d, 0xee, 0x89, + 0x78, 0x45, 0x23, 0x3c, 0x8f, 0x79, 0x39, 0xb8, 0xc5, 0xad, 0xf9, 0x01, + 0xcd, 0xd5, 0xc6, 0x92, 0xff, 0x80, 0xb2, 0xf9, 0x47, 0x11, 0x23, 0x5c, + 0x50, 0x83, 0xd5, 0x35, 0x7a, 0xab, 0xa3, 0x7c, 0x29, 0xa8, 0xf1, 0x25, + 0xab, 0xc6, 0x97, 0x2c, 0x97, 0xae, 0xda, 0xfb, 0xe1, 0x22, 0x76, 0xdf, + 0x7e, 0xac, 0x6f, 0xcc, 0xc9, 0xf2, 0x6c, 0x70, 0x01, 0x1d, 0x9f, 0xfb, + 0xa9, 0xbe, 0x7a, 0x69, 0xe4, 0xaa, 0x38, 0xe8, 0xfd, 0x7b, 0x5f, 0xdc, + 0xaf, 0x12, 0x95, 0xf7, 0x2e, 0x44, 0xcf, 0xc6, 0xb8, 0x11, 0xb5, 0xf7, + 0xf0, 0xa5, 0x84, 0xb2, 0x16, 0xc9, 0x18, 0xa9, 0x52, 0x72, 0x21, 0x3e, + 0x03, 0xda, 0x81, 0xad, 0xc2, 0x88, 0xf7, 0x48, 0xe4, 0x80, 0x72, 0x41, + 0xe5, 0xf0, 0xec, 0x8b, 0xc8, 0x47, 0xca, 0xf5, 0xe5, 0x53, 0xd3, 0x76, + 0x03, 0x8c, 0x07, 0x6a, 0x63, 0x25, 0x0d, 0xfe, 0xe5, 0x10, 0xe4, 0x24, + 0x9d, 0x49, 0x12, 0xbf, 0xb8, 0xbf, 0x0e, 0x25, 0x1b, 0xba, 0x43, 0x8a, + 0xfa, 0x65, 0x18, 0x47, 0x3d, 0x24, 0x80, 0x28, 0x8f, 0xed, 0x59, 0x51, + 0x0c, 0xbd, 0x5b, 0xb1, 0x9d, 0x9e, 0xef, 0xea, 0x15, 0x49, 0x93, 0x83, + 0xb1, 0x79, 0xcd, 0x65, 0x75, 0xc2, 0x71, 0x9e, 0x7a, 0xd0, 0xa3, 0xef, + 0xe4, 0xc8, 0xc8, 0x52, 0x64, 0xa6, 0xc7, 0xeb, 0xe2, 0xc1, 0x25, 0x8f, + 0x3d, 0x14, 0xf7, 0x65, 0x40, 0xf5, 0x21, 0x26, 0x2b, 0x6e, 0x27, 0xe6, + 0xb1, 0x43, 0x1e, 0xd4, 0x87, 0x45, 0x98, 0xef, 0x11, 0x65, 0xd1, 0x4f, + 0xc4, 0x0a, 0x6d, 0xbe, 0x9f, 0x3d, 0xc8, 0x3c, 0x4f, 0xed, 0xa8, 0x33, + 0x3f, 0x26, 0x0d, 0x33, 0x91, 0x1a, 0xfa, 0xa3, 0x17, 0x2f, 0xd1, 0xfd, + 0x80, 0xb4, 0x0d, 0x34, 0x1b, 0xce, 0x9f, 0x64, 0x91, 0x37, 0x66, 0xf8, + 0x9e, 0xde, 0xf2, 0xbe, 0x9a, 0x52, 0x76, 0x70, 0x19, 0x5d, 0x37, 0x22, + 0xc8, 0xb4, 0xde, 0xd9, 0x90, 0xe0, 0x7f, 0xd0, 0x0f, 0x79, 0xd4, 0x83, + 0x24, 0xb5, 0x31, 0x03, 0xbd, 0xc5, 0x7d, 0x9a, 0x25, 0x22, 0xad, 0xc5, + 0x51, 0xfe, 0xa6, 0xad, 0x06, 0xa9, 0x27, 0x21, 0xde, 0xb7, 0x6f, 0xcb, + 0x71, 0xcd, 0x8e, 0xfb, 0xe6, 0xb6, 0xf1, 0xc8, 0xfd, 0x39, 0xe8, 0xf1, + 0x64, 0x28, 0x79, 0x40, 0xc7, 0xb5, 0x13, 0x80, 0x3c, 0x27, 0x00, 0xb5, + 0xbf, 0xc8, 0x46, 0xe8, 0x2e, 0xa2, 0xc7, 0x31, 0x6d, 0xdc, 0xa1, 0x9a, + 0xeb, 0xf6, 0x7c, 0x5e, 0x88, 0x4e, 0x8c, 0x5d, 0xe6, 0xff, 0xdd, 0x58, + 0xb2, 0xd7, 0xda, 0xf2, 0x81, 0x5e, 0x4f, 0xdf, 0xd7, 0x6d, 0xf9, 0x8c, + 0xdc, 0x6b, 0x06, 0xbd, 0xd3, 0xfb, 0xbe, 0x49, 0x3e, 0xb0, 0xb6, 0x5d, + 0x8c, 0x2e, 0x1e, 0xb0, 0xb6, 0x53, 0xaf, 0x0e, 0xd4, 0x87, 0xb6, 0xe6, + 0xf5, 0xaf, 0x77, 0xf4, 0x25, 0x3a, 0x66, 0x41, 0x6d, 0xdc, 0x2c, 0x41, + 0xea, 0x25, 0x65, 0x5e, 0x89, 0xfa, 0xeb, 0xa0, 0xef, 0xff, 0xe3, 0x6b, + 0xa6, 0x0c, 0x04, 0xbb, 0xe6, 0xf7, 0xe7, 0xbf, 0xf2, 0xbe, 0x66, 0x11, + 0x09, 0xe3, 0x31, 0xb5, 0x95, 0x78, 0xe7, 0x78, 0x4b, 0xbc, 0xa4, 0xa7, + 0xa3, 0xd8, 0xd4, 0x26, 0xc1, 0xe8, 0x1b, 0x58, 0xec, 0x3d, 0xd8, 0x88, + 0xc4, 0xf0, 0x9d, 0x1d, 0xc9, 0x1d, 0x86, 0x05, 0x57, 0xee, 0x2c, 0x60, + 0x52, 0x3a, 0x8f, 0x27, 0x1f, 0x37, 0x10, 0xd7, 0x1c, 0xaf, 0xe1, 0xe4, + 0x1c, 0x2f, 0x39, 0xb5, 0x45, 0x32, 0xb5, 0x6f, 0x43, 0x10, 0x5f, 0x29, + 0x4f, 0xc2, 0x1d, 0x3e, 0xe0, 0x4d, 0xed, 0xd0, 0xa6, 0xe9, 0x1f, 0xa7, + 0xb1, 0x14, 0xda, 0x09, 0x85, 0xe8, 0x30, 0x4a, 0xf0, 0x0e, 0xcf, 0x75, + 0x2e, 0xc0, 0x7f, 0xd2, 0x49, 0x73, 0x47, 0x10, 0xa9, 0xa2, 0xb5, 0xcd, + 0x5a, 0x92, 0x5e, 0x7b, 0x31, 0x6a, 0x45, 0x8d, 0x86, 0x4c, 0x4e, 0x8d, + 0xdc, 0x70, 0xdb, 0x5d, 0x2e, 0x01, 0xa2, 0xd1, 0xe7, 0x07, 0xc7, 0x88, + 0x49, 0x0b, 0xa8, 0xc7, 0xa6, 0x65, 0x8b, 0x84, 0xbc, 0xfe, 0x88, 0x6b, + 0xd9, 0xfb, 0x7e, 0x4b, 0xc9, 0xc5, 0xe8, 0x85, 0x7e, 0x73, 0x19, 0x2f, + 0x5b, 0xdb, 0xc9, 0xe4, 0x68, 0x77, 0x9d, 0x8b, 0x29, 0x89, 0x46, 0x77, + 0x0f, 0xfe, 0x5d, 0xbd, 0x13, 0xb9, 0x43, 0x9d, 0x0d, 0x84, 0x4f, 0x07, + 0xc0, 0x7a, 0x9b, 0x07, 0xe0, 0x7b, 0x78, 0x6e, 0x6a, 0x93, 0x8b, 0xc9, + 0xb6, 0x84, 0x04, 0xc6, 0xfd, 0x97, 0xdc, 0xfe, 0xc8, 0xf1, 0xc3, 0x8f, + 0x98, 0xb9, 0x13, 0xcc, 0x36, 0xef, 0x36, 0xe0, 0xac, 0xd4, 0xd7, 0xac, + 0x42, 0x16, 0x2c, 0x5a, 0xc4, 0x36, 0x98, 0xda, 0xe9, 0x77, 0x7d, 0x6d, + 0x1d, 0xc5, 0xe4, 0x97, 0x4c, 0xc9, 0xa3, 0xc5, 0xe4, 0x15, 0x79, 0x3e, + 0x1c, 0xbd, 0x99, 0xc5, 0xb2, 0x19, 0x71, 0xbd, 0x9a, 0xb9, 0xf6, 0xfa, + 0x1e, 0xee, 0xda, 0x6b, 0xd3, 0x75, 0xd7, 0xf3, 0xb8, 0xff, 0xfc, 0xfd, + 0xf9, 0xe4, 0xda, 0xeb, 0xa7, 0xae, 0xbb, 0xce, 0xbf, 0x2e, 0xbe, 0xfc, + 0xeb, 0xbe, 0x1f, 0x7f, 0xdd, 0xf5, 0xee, 0xeb, 0xde, 0x37, 0x5c, 0x17, + 0xde, 0x7b, 0x98, 0x9f, 0xcc, 0x99, 0x1b, 0x66, 0x09, 0xcb, 0x56, 0x05, + 0xaa, 0x57, 0x26, 0x27, 0x80, 0x76, 0x21, 0xdd, 0x56, 0xba, 0xb0, 0x0c, + 0x2f, 0xae, 0xfe, 0x9a, 0x24, 0xb0, 0x2e, 0x9d, 0x0b, 0xd6, 0x4b, 0x3e, + 0xb0, 0x4e, 0xc1, 0xe3, 0xef, 0xf1, 0x18, 0x40, 0x64, 0x22, 0xb6, 0xe3, + 0xb3, 0x2d, 0x88, 0xa7, 0x10, 0x33, 0xe6, 0x81, 0xf5, 0xce, 0x4d, 0xeb, + 0xd6, 0x57, 0xad, 0x16, 0x2a, 0x56, 0xad, 0xa9, 0x58, 0x29, 0xac, 0x59, + 0x2e, 0x64, 0x6e, 0x10, 0x56, 0x96, 0x7c, 0x47, 0xa8, 0xf0, 0x57, 0x57, + 0xaf, 0x59, 0x2f, 0x2c, 0xab, 0x12, 0xaa, 0x6a, 0xfd, 0x15, 0xeb, 0x57, + 0x6d, 0x12, 0xfc, 0x15, 0x4a, 0xa0, 0x6a, 0x63, 0x55, 0x25, 0xd4, 0x0d, + 0x81, 0x95, 0x89, 0x79, 0xa1, 0x0e, 0xf4, 0x97, 0x2a, 0xd6, 0x56, 0xf9, + 0xd7, 0x57, 0x09, 0xeb, 0xd6, 0x57, 0xce, 0x9a, 0x55, 0x59, 0xf5, 0xd0, + 0x86, 0x2a, 0x61, 0x95, 0x7f, 0xed, 0x83, 0x55, 0x6b, 0x85, 0xf5, 0x8a, + 0xbf, 0x5a, 0x58, 0xed, 0xaf, 0x7d, 0x60, 0x5d, 0xe0, 0x3b, 0x55, 0xd9, + 0x39, 0xb0, 0x61, 0x1d, 0x9e, 0x55, 0x57, 0x54, 0x3d, 0xb0, 0x6c, 0x0d, + 0x7e, 0x36, 0xfb, 0x66, 0xa1, 0x74, 0xe1, 0x5d, 0x37, 0x16, 0x3c, 0x70, + 0xfb, 0x9c, 0x25, 0xb0, 0x71, 0x4d, 0xa0, 0x52, 0xd8, 0x50, 0x53, 0x89, + 0x01, 0x3d, 0x70, 0xcd, 0x6b, 0xd9, 0xfe, 0x65, 0xeb, 0xd6, 0xac, 0xda, + 0x80, 0xb7, 0xd7, 0x07, 0x56, 0xe3, 0x5f, 0xee, 0x64, 0x61, 0x43, 0xa0, + 0x7a, 0x3d, 0x7e, 0xb6, 0x3e, 0x07, 0xa6, 0x29, 0x6b, 0x56, 0x57, 0x4d, + 0xab, 0xf2, 0xaf, 0x5d, 0x55, 0x35, 0x6d, 0xce, 0xda, 0x4a, 0x7c, 0xb0, + 0x66, 0x9a, 0xe2, 0x5f, 0x5b, 0xf9, 0xb0, 0x7f, 0x6d, 0xd5, 0xb4, 0x9a, + 0x40, 0xc5, 0x9a, 0x69, 0x6b, 0x6b, 0xa6, 0xbb, 0x0b, 0xdc, 0xd3, 0xb4, + 0x8b, 0x29, 0xeb, 0x2a, 0x57, 0x4e, 0x5b, 0xb7, 0xb6, 0x62, 0x5a, 0xc5, + 0x9a, 0xd5, 0xab, 0xd7, 0x54, 0x6b, 0xf7, 0x1e, 0x58, 0xe6, 0x5f, 0x57, + 0x35, 0x0d, 0x63, 0x5b, 0xb5, 0xa1, 0x52, 0xff, 0x64, 0xfd, 0xa6, 0x9a, + 0xaa, 0x75, 0x53, 0x15, 0x58, 0xec, 0x5f, 0x57, 0xb3, 0xac, 0x6a, 0xed, + 0xda, 0x4d, 0xc2, 0xa2, 0x00, 0x2c, 0xc2, 0x27, 0x7a, 0x0c, 0x20, 0xad, + 0xc1, 0x28, 0x04, 0xdf, 0x5c, 0x1f, 0x18, 0x88, 0x85, 0xf9, 0x09, 0x79, + 0x8c, 0x58, 0xc8, 0x4f, 0xc0, 0x60, 0xb1, 0x91, 0x1c, 0xc3, 0x18, 0xc8, + 0x24, 0xbb, 0x0d, 0x1b, 0xc8, 0x16, 0x66, 0x37, 0xd9, 0xc0, 0x6e, 0x21, + 0xf8, 0x86, 0xdb, 0x92, 0x3f, 0x66, 0x4b, 0xe6, 0xe6, 0xdd, 0xcc, 0x06, + 0xf3, 0x16, 0xa3, 0xa5, 0x50, 0x3b, 0x27, 0xf4, 0xdc, 0x90, 0x94, 0x50, + 0xc8, 0x5c, 0xbd, 0xec, 0xe8, 0xc0, 0x97, 0x8d, 0x34, 0x38, 0x83, 0xc9, + 0xd6, 0x93, 0xa3, 0x6a, 0x41, 0x99, 0xf5, 0xa0, 0xcc, 0x18, 0x94, 0x99, + 0x46, 0x40, 0x03, 0xdf, 0xa1, 0x05, 0xbe, 0x83, 0xbe, 0x07, 0xb9, 0x31, + 0x64, 0x8c, 0x59, 0x31, 0xd8, 0x6d, 0xc4, 0x77, 0xa0, 0x43, 0x4f, 0x11, + 0xf3, 0x7f, 0x28, 0x45, 0xe6, 0x44, 0x60, 0x18, 0x06, 0xc0, 0xc2, 0x01, + 0x10, 0x3c, 0xe1, 0x0c, 0x13, 0xb1, 0x49, 0x1a, 0x26, 0x22, 0x95, 0x73, + 0x13, 0x19, 0xc6, 0x30, 0xd1, 0x08, 0xc4, 0x64, 0xd8, 0xc2, 0x9a, 0xc1, + 0x6a, 0xe1, 0x08, 0x30, 0xb4, 0x15, 0x9a, 0x0c, 0x0c, 0xe3, 0xa5, 0x87, + 0x47, 0xe8, 0x81, 0xce, 0xb5, 0x2f, 0x1b, 0x06, 0xeb, 0x1a, 0x44, 0xbb, + 0x1d, 0x84, 0xef, 0xe2, 0x71, 0xe1, 0x1a, 0x61, 0x5d, 0x4d, 0xa0, 0x9a, + 0x36, 0xb9, 0x75, 0x02, 0x56, 0x95, 0xe0, 0xdf, 0xe8, 0x0f, 0xac, 0xf2, + 0x2f, 0x5b, 0x55, 0x05, 0xf8, 0x68, 0xc3, 0x3a, 0x6c, 0x3a, 0xa5, 0x8b, + 0xbf, 0x75, 0xfd, 0xa3, 0x12, 0xbd, 0x62, 0x05, 0x3f, 0x36, 0xaf, 0xd5, + 0x42, 0x66, 0x25, 0x9e, 0x60, 0xcb, 0xab, 0xdc, 0x84, 0x8d, 0xd7, 0x8f, + 0x6d, 0xa3, 0x92, 0x7e, 0x5c, 0xb3, 0x76, 0xcd, 0x83, 0x6b, 0xfd, 0xab, + 0x31, 0x7c, 0x7f, 0x85, 0x16, 0xda, 0xa2, 0xd2, 0x3b, 0xb0, 0x65, 0xd2, + 0xf6, 0xb9, 0x9a, 0xb6, 0xe0, 0xea, 0xaa, 0xeb, 0x83, 0x9d, 0x2c, 0x2c, + 0xdf, 0x50, 0x5d, 0xb1, 0x3e, 0xb0, 0xa6, 0x7a, 0x96, 0x00, 0xfe, 0x75, + 0x18, 0x39, 0x3d, 0x17, 0x5c, 0x99, 0xeb, 0x5c, 0xc2, 0x72, 0x7c, 0xa9, + 0xaa, 0x72, 0x96, 0xb0, 0x1c, 0x0f, 0xda, 0x9d, 0xc9, 0x02, 0x52, 0x5e, + 0x15, 0xc6, 0x9d, 0xb9, 0x2e, 0x73, 0x5d, 0x02, 0x24, 0xe4, 0xe6, 0xe6, + 0x0a, 0x8b, 0xe6, 0x2c, 0x2c, 0xf5, 0x09, 0x78, 0x96, 0xa0, 0x25, 0x51, + 0x88, 0x87, 0x41, 0xe9, 0x70, 0xc7, 0x56, 0xb0, 0x26, 0x3f, 0x0a, 0xd6, + 0x9b, 0x11, 0xef, 0x21, 0xfe, 0xed, 0xb1, 0xb8, 0x0f, 0xec, 0x5f, 0x7c, + 0x1f, 0xac, 0x2d, 0x88, 0x76, 0xc4, 0x43, 0x3f, 0x00, 0xeb, 0xdd, 0xf5, + 0xf1, 0xfb, 0x77, 0x57, 0x23, 0xc1, 0x54, 0x62, 0x8c, 0x34, 0xfb, 0x82, + 0xbb, 0x36, 0xb3, 0x36, 0x01, 0xaa, 0x6a, 0x68, 0x4e, 0x33, 0xd7, 0x09, + 0x0f, 0xfb, 0xd7, 0x5d, 0xc9, 0xf0, 0xd5, 0xd4, 0xfb, 0xfc, 0xd5, 0x93, + 0x90, 0x02, 0xd7, 0x54, 0xaf, 0x0f, 0x54, 0x23, 0xe1, 0xd5, 0x2e, 0xc7, + 0xb2, 0xc3, 0xd4, 0x07, 0xaa, 0x91, 0x68, 0x03, 0x1b, 0x91, 0x7a, 0xf5, + 0xcf, 0x61, 0xcd, 0x86, 0xf5, 0x10, 0xa8, 0x86, 0xff, 0xf6, 0xdf, 0x3e, + 0x03, 0x20, 0x59, 0x17, 0x63, 0x5c, 0xcb, 0x61, 0xe1, 0x9c, 0x85, 0x50, + 0xed, 0xaf, 0x46, 0x69, 0xd0, 0x9d, 0x3f, 0xdd, 0x53, 0x30, 0xe3, 0xc6, + 0x9b, 0x0a, 0x67, 0xce, 0x91, 0x7c, 0x73, 0xe7, 0x15, 0x8f, 0xb8, 0xe1, + 0x5f, 0x56, 0x51, 0x59, 0xb5, 0x1c, 0xaa, 0x32, 0x57, 0x55, 0xd2, 0xef, + 0x67, 0x20, 0xe8, 0xbc, 0xc2, 0x9b, 0x2c, 0xb6, 0x38, 0x3d, 0xcc, 0x82, + 0x6f, 0xb8, 0xf7, 0x4a, 0x7d, 0xe7, 0x53, 0x87, 0xdf, 0xd9, 0x33, 0xdb, + 0xf3, 0xcc, 0xb3, 0xa7, 0xc4, 0x8b, 0xa5, 0x33, 0x6f, 0x7e, 0xe6, 0xc2, + 0xdc, 0xa1, 0x94, 0x03, 0xd3, 0x5b, 0x9e, 0x7a, 0xe2, 0x4f, 0xe6, 0x97, + 0xcb, 0x33, 0x7d, 0x6b, 0xfe, 0xb5, 0x32, 0xdb, 0xa8, 0x8c, 0x02, 0xe1, + 0xf2, 0x2f, 0x9b, 0xfe, 0x84, 0xaf, 0xfd, 0xb6, 0x59, 0xaf, 0xfd, 0x71, + 0x57, 0x7e, 0xfa, 0x8d, 0x39, 0xda, 0x8f, 0x7c, 0xc3, 0x2f, 0xfe, 0x5c, + 0xd2, 0x7e, 0xcc, 0x37, 0xfc, 0xe8, 0x53, 0x01, 0xfe, 0x2f, 0xff, 0x4a, + 0xab, 0x97, 0x07, 0xaa, 0x03, 0xeb, 0x37, 0xc1, 0x42, 0xff, 0x42, 0x58, + 0x3c, 0x6f, 0xde, 0xc2, 0xbb, 0x90, 0x12, 0x56, 0x21, 0xed, 0x09, 0xeb, + 0x36, 0x54, 0x54, 0x54, 0x55, 0x55, 0x22, 0xe1, 0x4c, 0x7b, 0x78, 0xcd, + 0xda, 0x95, 0x95, 0x81, 0xb5, 0xd3, 0xd6, 0x56, 0xd5, 0xac, 0x99, 0x56, + 0x5d, 0xf5, 0xf0, 0xaa, 0xc0, 0xb2, 0xcb, 0x07, 0x44, 0xc5, 0x34, 0xec, + 0xdb, 0xe9, 0x79, 0xe5, 0xfa, 0x35, 0xfe, 0xa9, 0x15, 0x20, 0xfd, 0xef, + 0x7e, 0xff, 0x20, 0x0d, 0x60, 0xca, 0x83, 0x55, 0xeb, 0x95, 0xaa, 0x5a, + 0x0c, 0x67, 0x2a, 0x26, 0xef, 0x77, 0xfa, 0x7a, 0x9c, 0x7d, 0x28, 0xa7, + 0x2d, 0xba, 0xe3, 0xce, 0xd2, 0x25, 0xff, 0xe5, 0xc0, 0x56, 0xd7, 0xac, + 0xad, 0xaa, 0xc0, 0x50, 0xe2, 0x3f, 0x03, 0xc2, 0x86, 0xf8, 0x1f, 0xff, + 0x4b, 0xed, 0xe3, 0x8d, 0x04, 0xa8, 0xeb, 0xb9, 0x69, 0xd3, 0xb1, 0x39, + 0xbe, 0x71, 0xd5, 0x86, 0xb6, 0xb6, 0x97, 0x82, 0xc5, 0x5f, 0x5d, 0xba, + 0xf5, 0x53, 0xf6, 0x8e, 0xc2, 0xdb, 0xa7, 0x8f, 0x77, 0x5f, 0x2a, 0x79, + 0xf8, 0x91, 0x7b, 0x67, 0x1f, 0x5d, 0xb7, 0xb9, 0xfb, 0x8e, 0x31, 0x1b, + 0xe2, 0xa1, 0xd2, 0x79, 0x26, 0xfa, 0xa3, 0xfb, 0x14, 0xe9, 0xef, 0x9e, + 0xf8, 0xd1, 0xfb, 0xa3, 0xf8, 0x71, 0xdb, 0xb1, 0xf8, 0x71, 0x45, 0x9f, + 0x76, 0xac, 0x7b, 0x74, 0xea, 0x1c, 0x7a, 0x0c, 0x8f, 0xae, 0xd0, 0x8e, + 0x8f, 0xfe, 0xf9, 0x29, 0xed, 0x58, 0xf5, 0xc7, 0x3f, 0xd2, 0xa3, 0xf0, + 0xc0, 0x3e, 0x46, 0xc2, 0xe3, 0x27, 0x1b, 0x4b, 0x6e, 0xa2, 0xc7, 0xfd, + 0xbb, 0xec, 0xab, 0xf1, 0xe8, 0xfd, 0x68, 0x8f, 0x7b, 0x3f, 0x1e, 0x1b, + 0x32, 0x7e, 0xf7, 0xca, 0xbb, 0x78, 0x2c, 0xc8, 0xfa, 0x6a, 0x65, 0x92, + 0xef, 0x72, 0x3a, 0x61, 0x5f, 0xe7, 0x63, 0xff, 0x54, 0xb0, 0xd1, 0x07, + 0x6f, 0x2c, 0x7c, 0x70, 0xf5, 0xab, 0x07, 0x7d, 0x70, 0xf3, 0x0e, 0xf9, + 0xc3, 0x25, 0xef, 0xf9, 0xbc, 0x4f, 0xb4, 0xd5, 0x8e, 0xff, 0xf9, 0x98, + 0xb9, 0x8b, 0x3e, 0x7f, 0xff, 0xdd, 0x0f, 0xed, 0x65, 0x73, 0x77, 0x9e, + 0xba, 0xdd, 0xf8, 0xa7, 0xde, 0xba, 0xb9, 0x17, 0x17, 0xbc, 0xf7, 0x3a, + 0x33, 0xa5, 0x6d, 0xee, 0x2f, 0x5b, 0x4e, 0x6f, 0xf2, 0xd5, 0x7e, 0x36, + 0x57, 0x9c, 0xe2, 0xce, 0x13, 0x40, 0x59, 0x75, 0x1b, 0x54, 0x2d, 0x7f, + 0x70, 0x5e, 0xf1, 0x7c, 0x9a, 0x9e, 0xe4, 0xb2, 0x9a, 0x36, 0xea, 0xb1, + 0x60, 0x4c, 0x24, 0x9c, 0x19, 0xf3, 0x4c, 0x31, 0xe6, 0x55, 0x41, 0xef, + 0x47, 0x97, 0xc8, 0xc4, 0xbc, 0xd5, 0xa2, 0x64, 0x09, 0x43, 0xef, 0xd1, + 0x4b, 0xc6, 0xb2, 0x46, 0x29, 0x1a, 0x31, 0x94, 0xa5, 0xd7, 0xd8, 0x51, + 0x73, 0x1f, 0x8c, 0xa0, 0xfe, 0x74, 0xa9, 0xa6, 0xfd, 0x6d, 0xec, 0xcf, + 0xa7, 0x86, 0xff, 0xbd, 0xe3, 0x4f, 0x78, 0x0c, 0x8b, 0xee, 0x36, 0x98, + 0x08, 0x4e, 0x87, 0x31, 0xfd, 0x9f, 0x0c, 0xca, 0xe7, 0x5f, 0x5a, 0xb7, + 0xae, 0xfd, 0x15, 0xf5, 0xef, 0x1e, 0xf7, 0xb5, 0x6a, 0xd8, 0xc4, 0x28, + 0x9b, 0xa7, 0x18, 0x4f, 0x73, 0x0f, 0xd1, 0xab, 0x51, 0xf2, 0xd6, 0x2f, + 0xad, 0xdb, 0xdc, 0xed, 0x57, 0xcf, 0x85, 0xa3, 0x1f, 0xaa, 0x5a, 0x08, + 0x99, 0x0e, 0xa3, 0xa3, 0xb6, 0xfc, 0x30, 0x47, 0x43, 0x78, 0x64, 0xed, + 0xaf, 0x34, 0xaf, 0x92, 0x5a, 0x08, 0xdc, 0x44, 0xee, 0x9f, 0x88, 0x82, + 0x5a, 0x6b, 0x18, 0x26, 0x27, 0x9c, 0x61, 0x1f, 0xf2, 0x6d, 0x22, 0x1e, + 0x9f, 0x16, 0x1a, 0x88, 0x89, 0xf2, 0x23, 0x57, 0xc2, 0x4b, 0xd6, 0xce, + 0x85, 0xa3, 0xdd, 0x2a, 0x4b, 0xfd, 0x89, 0xd3, 0x70, 0x1e, 0x5d, 0xfb, + 0x2b, 0xe6, 0x4a, 0x4a, 0x38, 0x57, 0xf3, 0xb7, 0x21, 0x37, 0xe9, 0x4c, + 0x18, 0x65, 0xe8, 0xd1, 0xc6, 0xd1, 0x8a, 0xfd, 0x21, 0x87, 0x12, 0xf7, + 0x01, 0x6b, 0x97, 0x1f, 0xc5, 0x2f, 0xad, 0xed, 0xe6, 0x8c, 0xaf, 0xc2, + 0x20, 0x24, 0xc8, 0x7f, 0x57, 0xa3, 0x6d, 0x19, 0x28, 0xe6, 0x1b, 0x60, + 0x1c, 0x60, 0xaa, 0x14, 0x12, 0xcc, 0xd1, 0xf3, 0x95, 0x70, 0x25, 0xb4, + 0x9c, 0x4d, 0x30, 0x31, 0x57, 0xd9, 0x9c, 0x63, 0x3e, 0x4d, 0x9a, 0x72, + 0xb4, 0xd4, 0xa4, 0x69, 0xf9, 0x21, 0xc2, 0x70, 0xfb, 0xd5, 0xab, 0x42, + 0xd4, 0xe6, 0xa0, 0xb7, 0x00, 0xf5, 0xa1, 0xee, 0xb0, 0x00, 0x5f, 0xa8, + 0x7d, 0x6d, 0x29, 0xd4, 0x1b, 0x53, 0xaf, 0x78, 0xa9, 0xdf, 0x45, 0x77, + 0x84, 0x82, 0xb8, 0x93, 0x8e, 0x70, 0x39, 0xa9, 0xce, 0xa0, 0xd9, 0x4e, + 0xb2, 0xad, 0x9c, 0xd3, 0x22, 0x31, 0x9d, 0x5c, 0x64, 0x17, 0xf5, 0x14, + 0xeb, 0x5a, 0x2c, 0x9d, 0x18, 0x47, 0xe7, 0x02, 0x7e, 0x1d, 0xeb, 0x6b, + 0x27, 0x5f, 0x4b, 0x43, 0xcc, 0xc5, 0x3c, 0xc4, 0xc4, 0xf3, 0xe0, 0x8c, + 0x97, 0xa6, 0xf7, 0x28, 0xd5, 0x44, 0x88, 0x5e, 0x86, 0x89, 0x57, 0x3c, + 0xde, 0x62, 0x99, 0xa1, 0x86, 0xdc, 0x75, 0xd8, 0xf7, 0x10, 0xe4, 0x99, + 0x23, 0xb1, 0x89, 0xf1, 0xda, 0x88, 0x97, 0x9e, 0xf7, 0xa8, 0xb5, 0x7d, + 0x64, 0x69, 0x46, 0x55, 0x00, 0xf3, 0x02, 0x6b, 0x5b, 0x2a, 0xb6, 0x8b, + 0x04, 0xd4, 0x1e, 0x8d, 0x25, 0xa6, 0xd2, 0x72, 0x43, 0xba, 0xf2, 0xbb, + 0x45, 0x9c, 0x67, 0xbb, 0xd4, 0x1f, 0x41, 0xbd, 0xac, 0x86, 0xda, 0xd4, + 0xf9, 0xc8, 0x01, 0x42, 0x41, 0x2a, 0xf2, 0x2f, 0xa2, 0xf9, 0x22, 0x2b, + 0x23, 0x9e, 0xc6, 0xf9, 0xf4, 0x3e, 0xde, 0x13, 0xe8, 0xca, 0x36, 0x43, + 0x19, 0xe3, 0x76, 0x28, 0xc0, 0x2c, 0xf1, 0x76, 0x88, 0x21, 0xe0, 0xbd, + 0x0c, 0xca, 0xfd, 0x54, 0xaf, 0x49, 0xaa, 0x23, 0xde, 0xa4, 0x06, 0xe2, + 0xed, 0x6d, 0x4b, 0x9b, 0xc4, 0x67, 0xa1, 0x4e, 0xb9, 0x8d, 0x34, 0x30, + 0x3b, 0x0a, 0xb7, 0x39, 0x4b, 0xd3, 0xa0, 0x71, 0xbe, 0x67, 0x1b, 0x65, + 0x23, 0x85, 0xdb, 0xe8, 0xd9, 0x84, 0x52, 0xb6, 0x81, 0x9e, 0xd1, 0xd9, + 0xe5, 0x5f, 0xc5, 0x9e, 0x9d, 0xcf, 0x86, 0x1a, 0xe7, 0x53, 0x5f, 0x82, + 0xe1, 0x58, 0x87, 0x4b, 0x04, 0xb3, 0xb0, 0xd8, 0x30, 0xfa, 0x56, 0x27, + 0xd8, 0x7c, 0xa6, 0x08, 0x11, 0xa8, 0x6f, 0xb2, 0x43, 0xf3, 0xa9, 0x1e, + 0x4a, 0x75, 0xd2, 0x1d, 0x2b, 0x92, 0xc1, 0xe0, 0x9d, 0x29, 0x25, 0x62, + 0x9b, 0xb1, 0x84, 0x6d, 0x8e, 0xe4, 0x1c, 0x63, 0x27, 0x69, 0x22, 0xb3, + 0x2d, 0xb5, 0xa3, 0x96, 0xe3, 0x31, 0x9f, 0xec, 0x80, 0x29, 0xef, 0x85, + 0x21, 0xef, 0x2f, 0xe1, 0x51, 0xd5, 0x4c, 0x0b, 0x29, 0xca, 0xa9, 0xc9, + 0x01, 0x92, 0xcf, 0xec, 0xf8, 0x33, 0xea, 0xd7, 0xa5, 0xa8, 0x8b, 0xcc, + 0x5b, 0x02, 0x50, 0xec, 0xa3, 0x7e, 0xe9, 0xb7, 0x61, 0x3d, 0x6c, 0xe7, + 0x1b, 0x25, 0xf6, 0x04, 0x88, 0xa6, 0x9e, 0xed, 0xf7, 0x6d, 0xbd, 0x8b, + 0xcc, 0x1a, 0x78, 0xc7, 0xda, 0xfe, 0xd6, 0x7d, 0xbf, 0xbb, 0x8b, 0x78, + 0x9a, 0xb1, 0x3c, 0xfa, 0x54, 0xd4, 0x4d, 0xf8, 0x06, 0x6d, 0x76, 0xa6, + 0x66, 0x3e, 0x5b, 0xbb, 0x5d, 0x1a, 0x08, 0x13, 0xf7, 0x45, 0x95, 0xf9, + 0xe5, 0x43, 0xc5, 0xa5, 0xe6, 0x52, 0xb0, 0xdc, 0x57, 0x0a, 0x3f, 0x9c, + 0xcb, 0xbc, 0x42, 0xf3, 0xce, 0x6a, 0xf7, 0xbc, 0x80, 0x77, 0xef, 0xa7, + 0x77, 0x59, 0xbc, 0x3b, 0xe2, 0xde, 0xbd, 0x97, 0xef, 0xc5, 0xc7, 0xcb, + 0x90, 0xe7, 0x8d, 0xd0, 0x01, 0x96, 0x6e, 0x00, 0xeb, 0xc8, 0xeb, 0x17, + 0xd6, 0x5f, 0x7b, 0xfd, 0xe4, 0xd2, 0x6b, 0xaf, 0x0f, 0xdc, 0x77, 0xed, + 0x75, 0xe9, 0x82, 0x6b, 0xaf, 0xbf, 0x28, 0xc5, 0xba, 0xfb, 0x2d, 0x81, + 0xd1, 0x84, 0x4a, 0x7a, 0xc4, 0xfb, 0xf8, 0x54, 0x94, 0xe1, 0x08, 0x61, + 0x34, 0xd3, 0x06, 0xda, 0x8f, 0x8c, 0x60, 0x26, 0xcc, 0x88, 0x73, 0x76, + 0xc4, 0x79, 0x2c, 0x7e, 0x68, 0x2b, 0x51, 0x48, 0xfe, 0x0f, 0x8b, 0x61, + 0x7e, 0x4d, 0xb1, 0xa5, 0x90, 0x94, 0x6e, 0x9b, 0x0f, 0xed, 0xce, 0x6f, + 0x83, 0xb5, 0xd0, 0x00, 0x1a, 0x1b, 0x6c, 0x48, 0x02, 0xe1, 0x13, 0x07, + 0x5c, 0x61, 0x89, 0x7d, 0x23, 0xce, 0xad, 0x23, 0x42, 0x5b, 0x84, 0xba, + 0x1f, 0xd5, 0xff, 0xee, 0x42, 0x2c, 0x46, 0xdc, 0x7e, 0x27, 0x02, 0xeb, + 0xe1, 0x4e, 0x14, 0x04, 0x7c, 0x88, 0x4c, 0xfc, 0xce, 0x4a, 0xd7, 0x26, + 0x42, 0x4f, 0x6c, 0xc2, 0x7f, 0xc0, 0xf6, 0xdc, 0xc8, 0x9e, 0x0b, 0xa8, + 0x0f, 0x10, 0x3d, 0xee, 0x91, 0xe3, 0x25, 0xf0, 0xff, 0xf9, 0x8f, 0x2e, + 0xca, 0x18, 0x59, 0x57, 0x74, 0xfc, 0xf5, 0xb2, 0xcf, 0x29, 0x8a, 0x67, + 0x75, 0x1c, 0xd2, 0xf1, 0x92, 0x8e, 0x0e, 0x1d, 0x6f, 0xe8, 0x08, 0xeb, + 0xe8, 0xd4, 0xd1, 0xa3, 0xe3, 0x13, 0x1d, 0xbd, 0x3a, 0xfa, 0x74, 0x80, + 0x29, 0x0e, 0xb3, 0x0e, 0xab, 0x0e, 0x5e, 0x87, 0xa0, 0x23, 0x5b, 0x87, + 0x5b, 0x47, 0xa1, 0x0e, 0xaf, 0x8e, 0x12, 0x1d, 0x8b, 0x74, 0x2c, 0xd1, + 0x21, 0xeb, 0x50, 0x74, 0xd4, 0xe8, 0xa8, 0xd5, 0x51, 0xa7, 0x63, 0x9b, + 0x8e, 0x06, 0x1d, 0x8d, 0x3a, 0xf6, 0xe9, 0x78, 0x56, 0xc7, 0x21, 0x1d, + 0x2f, 0xe9, 0xe8, 0xd0, 0xf1, 0x86, 0x8e, 0xb0, 0x8e, 0x4e, 0x1d, 0x3d, + 0x3a, 0x3e, 0xd1, 0xd1, 0xab, 0xa3, 0x4f, 0x07, 0x98, 0xe3, 0x30, 0xeb, + 0xb0, 0xea, 0xe0, 0x75, 0x08, 0x3a, 0xb2, 0x75, 0xb8, 0x75, 0x14, 0xea, + 0xf0, 0xea, 0x28, 0xd1, 0xb1, 0x48, 0xc7, 0x12, 0x1d, 0xb2, 0x0e, 0x45, + 0x47, 0x8d, 0x8e, 0x5a, 0x1d, 0x75, 0x3a, 0xb6, 0xe9, 0x68, 0xd0, 0xd1, + 0xa8, 0x63, 0x9f, 0x8e, 0x67, 0x75, 0x1c, 0xd2, 0xf1, 0x92, 0x8e, 0x0e, + 0x1d, 0x6f, 0xe8, 0x08, 0xeb, 0xe8, 0xd4, 0xd1, 0xa3, 0xe3, 0x13, 0x1d, + 0xbd, 0x3a, 0xfa, 0x74, 0x80, 0x25, 0x0e, 0xb3, 0x0e, 0xab, 0x0e, 0x5e, + 0x87, 0xa0, 0x23, 0x5b, 0x87, 0x5b, 0x47, 0xa1, 0x0e, 0xaf, 0x8e, 0x12, + 0x1d, 0x8b, 0x74, 0x2c, 0xd1, 0x21, 0xeb, 0x50, 0x74, 0xd4, 0xe8, 0xa8, + 0xd5, 0x51, 0xa7, 0x63, 0x9b, 0x8e, 0x06, 0x1d, 0x8d, 0x3a, 0xf6, 0xe9, + 0x78, 0x56, 0xc7, 0x21, 0x1d, 0x2f, 0xe9, 0xe8, 0xd0, 0xf1, 0x86, 0x8e, + 0xb0, 0x8e, 0x4e, 0x1d, 0x3d, 0x3a, 0x3e, 0xd1, 0xd1, 0xab, 0xa3, 0x4f, + 0x07, 0x24, 0xc4, 0x61, 0xd6, 0x61, 0xd5, 0xc1, 0xeb, 0x10, 0x74, 0x64, + 0xeb, 0x70, 0xeb, 0x28, 0xd4, 0xe1, 0xd5, 0x51, 0xa2, 0x63, 0x91, 0x8e, + 0x25, 0x3a, 0x64, 0x1d, 0x8a, 0x8e, 0x1a, 0x1d, 0xb5, 0x3a, 0xea, 0x74, + 0x6c, 0xd3, 0xd1, 0xa0, 0x83, 0xf6, 0xce, 0xbe, 0x7f, 0xd0, 0x67, 0xfc, + 0xbf, 0xfe, 0xfc, 0xa3, 0x8b, 0xc8, 0xa6, 0x7b, 0xe2, 0x6c, 0x24, 0x9b, + 0x21, 0xd6, 0xcb, 0x7a, 0xc5, 0x3f, 0x42, 0xec, 0x9a, 0x1f, 0xe5, 0x76, + 0x73, 0xee, 0xf4, 0x95, 0x96, 0xfe, 0x27, 0x31, 0xfd, 0xa3, 0xe7, 0xff, + 0xf8, 0x47, 0xbe, 0x81, 0xb3, 0x7e, 0xd3, 0xfd, 0xcb, 0xc7, 0xf7, 0x90, + 0xc7, 0x77, 0x57, 0x80, 0xf5, 0x8b, 0xd5, 0x60, 0x7d, 0x72, 0x00, 0xac, + 0x16, 0x09, 0xac, 0xaf, 0xce, 0x03, 0x6b, 0x4b, 0x09, 0x58, 0x5f, 0x28, + 0x03, 0xeb, 0x79, 0x7c, 0xf6, 0x3f, 0x01, 0xa8, 0x7b, 0x69, 0xf7, 0x10, + 0x11, 0x01, 0x00 +}; diff --git a/libraries/PicoOTA/examples/OTAfromFile/OTAfromFile.ino b/libraries/PicoOTA/examples/OTAfromFile/OTAfromFile.ino new file mode 100644 index 00000000..e40207e7 --- /dev/null +++ b/libraries/PicoOTA/examples/OTAfromFile/OTAfromFile.ino @@ -0,0 +1,39 @@ +// This example overwrites itself with a serial blinker sketch using OTA +// In general, you will get a file from the Internet, over a serial port, etc. +// and not include it in a header like we do here for simplicity. +// +// You need to have at least 256K of filesystem configured in +// Tools->Flash Size +// +// Released to the public domain August 2022 by Earle F. Philhower, III + +#include +#include +#include "blink_100_1000.h" + +void setup() { + Serial.begin(115200); + delay(5000); + + Serial.printf("Writing OTA image of blinker..."); + LittleFS.begin(); + File f = LittleFS.open("blink.bin", "w"); + if (sizeof(blink) != f.write(blink, sizeof(blink))) { + Serial.printf("Unable to write OTA binary. Is the filesystem size set?\n"); + return; + } + f.close(); + Serial.printf("done\n\n"); + Serial.printf("Programming OTA commands..."); + picoOTA.begin(); + picoOTA.addFile("blink.bin"); + picoOTA.commit(); + LittleFS.end(); + Serial.printf("done\n\n"); + Serial.printf("Rebooting in 5 seconds, should begin blinker instead of this app...\n"); + delay(5000); + rp2040.reboot(); +} + +void loop() { +} diff --git a/libraries/PicoOTA/examples/OTAfromFile/blink_100_1000.h b/libraries/PicoOTA/examples/OTAfromFile/blink_100_1000.h new file mode 100644 index 00000000..1d96dcfd --- /dev/null +++ b/libraries/PicoOTA/examples/OTAfromFile/blink_100_1000.h @@ -0,0 +1,5828 @@ +const unsigned char blink[] = { + 0x00, 0xb5, 0x32, 0x4b, 0x21, 0x20, 0x58, 0x60, 0x98, 0x68, 0x02, 0x21, + 0x88, 0x43, 0x98, 0x60, 0xd8, 0x60, 0x18, 0x61, 0x58, 0x61, 0x2e, 0x4b, + 0x00, 0x21, 0x99, 0x60, 0x02, 0x21, 0x59, 0x61, 0x01, 0x21, 0xf0, 0x22, + 0x99, 0x50, 0x2b, 0x49, 0x19, 0x60, 0x01, 0x21, 0x99, 0x60, 0x35, 0x20, + 0x00, 0xf0, 0x44, 0xf8, 0x02, 0x22, 0x90, 0x42, 0x14, 0xd0, 0x06, 0x21, + 0x19, 0x66, 0x00, 0xf0, 0x34, 0xf8, 0x19, 0x6e, 0x01, 0x21, 0x19, 0x66, + 0x00, 0x20, 0x18, 0x66, 0x1a, 0x66, 0x00, 0xf0, 0x2c, 0xf8, 0x19, 0x6e, + 0x19, 0x6e, 0x19, 0x6e, 0x05, 0x20, 0x00, 0xf0, 0x2f, 0xf8, 0x01, 0x21, + 0x08, 0x42, 0xf9, 0xd1, 0x00, 0x21, 0x99, 0x60, 0x1b, 0x49, 0x19, 0x60, + 0x00, 0x21, 0x59, 0x60, 0x1a, 0x49, 0x1b, 0x48, 0x01, 0x60, 0x01, 0x21, + 0x99, 0x60, 0xeb, 0x21, 0x19, 0x66, 0xa0, 0x21, 0x19, 0x66, 0x00, 0xf0, + 0x12, 0xf8, 0x00, 0x21, 0x99, 0x60, 0x16, 0x49, 0x14, 0x48, 0x01, 0x60, + 0x01, 0x21, 0x99, 0x60, 0x01, 0xbc, 0x00, 0x28, 0x00, 0xd0, 0x00, 0x47, + 0x12, 0x48, 0x13, 0x49, 0x08, 0x60, 0x03, 0xc8, 0x80, 0xf3, 0x08, 0x88, + 0x08, 0x47, 0x03, 0xb5, 0x99, 0x6a, 0x04, 0x20, 0x01, 0x42, 0xfb, 0xd0, + 0x01, 0x20, 0x01, 0x42, 0xf8, 0xd1, 0x03, 0xbd, 0x02, 0xb5, 0x18, 0x66, + 0x18, 0x66, 0xff, 0xf7, 0xf2, 0xff, 0x18, 0x6e, 0x18, 0x6e, 0x02, 0xbd, + 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x07, 0x00, + 0x00, 0x03, 0x5f, 0x00, 0x21, 0x22, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x18, + 0x22, 0x20, 0x00, 0xa0, 0x00, 0x01, 0x00, 0x10, 0x08, 0xed, 0x00, 0xe0, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x74, 0xb2, 0x4e, 0x7a, 0x00, 0x20, 0x04, 0x20, 0xf7, 0x01, 0x00, 0x10, + 0xc3, 0x01, 0x00, 0x10, 0xc5, 0x01, 0x00, 0x10, 0xc1, 0x01, 0x00, 0x10, + 0xc1, 0x01, 0x00, 0x10, 0xc1, 0x01, 0x00, 0x10, 0xc1, 0x01, 0x00, 0x10, + 0xc1, 0x01, 0x00, 0x10, 0xc1, 0x01, 0x00, 0x10, 0xc1, 0x01, 0x00, 0x10, + 0xc7, 0x01, 0x00, 0x10, 0xc1, 0x01, 0x00, 0x10, 0xc1, 0x01, 0x00, 0x10, + 0xc9, 0x01, 0x00, 0x10, 0xcb, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, 0xcd, 0x01, 0x00, 0x10, + 0xcd, 0x01, 0x00, 0x10, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, + 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xf0, 0x51, 0xf8, 0x10, 0x38, 0x00, 0xbe, + 0xf2, 0xeb, 0x88, 0x71, 0xe0, 0x02, 0x00, 0x10, 0xfc, 0x02, 0x00, 0x10, + 0x34, 0x02, 0x00, 0x10, 0x90, 0xa3, 0x1a, 0xe7, 0x00, 0x20, 0x24, 0x49, + 0x08, 0x60, 0x06, 0xc8, 0x81, 0xf3, 0x08, 0x88, 0x10, 0x47, 0x22, 0x48, + 0x00, 0x68, 0x00, 0x28, 0x35, 0xd1, 0x0d, 0xa4, 0x0e, 0xcc, 0x00, 0x29, + 0x02, 0xd0, 0x00, 0xf0, 0x12, 0xf8, 0xf9, 0xe7, 0x1d, 0x49, 0x1e, 0x4a, + 0x00, 0x20, 0x00, 0xe0, 0x01, 0xc1, 0x91, 0x42, 0xfc, 0xd1, 0x1c, 0x49, + 0x88, 0x47, 0x1c, 0x49, 0x88, 0x47, 0x1c, 0x49, 0x88, 0x47, 0x00, 0xbe, + 0xfd, 0xe7, 0x01, 0xc9, 0x01, 0xc2, 0x9a, 0x42, 0xfb, 0xd3, 0x70, 0x47, + 0xfc, 0x02, 0x00, 0x10, 0xc0, 0x00, 0x00, 0x20, 0xb0, 0x22, 0x00, 0x20, + 0xec, 0x24, 0x00, 0x10, 0xb0, 0x22, 0x00, 0x20, 0xbc, 0x25, 0x00, 0x20, + 0xf8, 0x27, 0x00, 0x10, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x04, 0x20, + 0xf8, 0x27, 0x00, 0x10, 0x00, 0x10, 0x04, 0x20, 0x00, 0x10, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x47, 0x0b, 0x48, 0x00, 0xf0, 0x18, 0xf8, + 0x00, 0x47, 0xef, 0xf3, 0x05, 0x80, 0xc0, 0xb2, 0x70, 0x47, 0x00, 0x00, + 0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xd0, 0xbc, 0x25, 0x00, 0x20, + 0xcc, 0xd5, 0x00, 0x20, 0x85, 0x1e, 0x00, 0x20, 0x5d, 0x01, 0x00, 0x20, + 0x99, 0x01, 0x00, 0x20, 0x57, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, + 0x0d, 0x1c, 0x00, 0x20, 0x06, 0x00, 0x52, 0x50, 0xab, 0xb3, 0x60, 0x53, + 0x21, 0x25, 0x00, 0x20, 0x06, 0x00, 0x52, 0x50, 0x86, 0x1c, 0x03, 0x02, + 0x2c, 0x25, 0x00, 0x20, 0x06, 0x00, 0x52, 0x50, 0x54, 0x22, 0xa2, 0x9d, + 0x30, 0x25, 0x00, 0x20, 0x05, 0x00, 0x52, 0x50, 0xde, 0x65, 0xf4, 0x68, + 0xf8, 0x27, 0x00, 0x10, 0xd4, 0x02, 0x00, 0x10, 0xc8, 0x02, 0x00, 0x10, + 0xbc, 0x02, 0x00, 0x10, 0x3c, 0x25, 0x00, 0x20, 0xb0, 0x02, 0x00, 0x10, + 0x48, 0x25, 0x00, 0x20, 0x54, 0x25, 0x00, 0x20, 0xf8, 0xb5, 0xc0, 0x46, + 0x04, 0x48, 0x05, 0x4b, 0x10, 0xb5, 0x83, 0x42, 0x03, 0xd0, 0x04, 0x4b, + 0x00, 0x2b, 0x00, 0xd0, 0x98, 0x47, 0x10, 0xbd, 0xbc, 0x25, 0x00, 0x20, + 0xbc, 0x25, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0x07, 0x49, + 0x09, 0x1a, 0x8b, 0x10, 0xc9, 0x0f, 0xc9, 0x18, 0x10, 0xb5, 0x49, 0x10, + 0x03, 0xd0, 0x04, 0x4b, 0x00, 0x2b, 0x00, 0xd0, 0x98, 0x47, 0x10, 0xbd, + 0xbc, 0x25, 0x00, 0x20, 0xbc, 0x25, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xb5, 0x07, 0x4c, 0x23, 0x78, 0x00, 0x2b, 0x09, 0xd1, 0xff, 0xf7, + 0xd5, 0xff, 0x05, 0x4b, 0x00, 0x2b, 0x02, 0xd0, 0x04, 0x48, 0x00, 0xe0, + 0x00, 0xbf, 0x01, 0x23, 0x23, 0x70, 0x10, 0xbd, 0xbc, 0x25, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xb0, 0x22, 0x00, 0x20, 0x05, 0x4b, 0x10, 0xb5, + 0x00, 0x2b, 0x03, 0xd0, 0x04, 0x49, 0x05, 0x48, 0x00, 0xe0, 0x00, 0xbf, + 0xff, 0xf7, 0xcc, 0xff, 0x10, 0xbd, 0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x25, 0x00, 0x20, 0xb0, 0x22, 0x00, 0x20, 0xb0, 0xb5, 0x82, 0xb0, + 0x00, 0xaf, 0x78, 0x60, 0x39, 0x60, 0x00, 0xf0, 0x19, 0xf8, 0x08, 0x4b, + 0x08, 0x4a, 0x9a, 0x60, 0x07, 0x4b, 0x1d, 0x68, 0x07, 0x4b, 0x1b, 0x68, + 0x1c, 0x00, 0x2b, 0x00, 0x9d, 0x46, 0xa0, 0x47, 0x00, 0x23, 0x18, 0x00, + 0xbd, 0x46, 0x02, 0xb0, 0xb0, 0xbd, 0xc0, 0x46, 0x00, 0xed, 0x00, 0xe0, + 0x00, 0x40, 0x00, 0x10, 0x04, 0x40, 0x00, 0x10, 0xfe, 0xe7, 0x00, 0x00, + 0x70, 0xb5, 0x4c, 0x49, 0x08, 0x22, 0x4c, 0x48, 0x86, 0xb0, 0x01, 0xf0, + 0xb9, 0xff, 0x4a, 0x49, 0x00, 0x28, 0x40, 0xd1, 0x01, 0x23, 0x0a, 0x00, + 0x01, 0x24, 0x48, 0x4d, 0x5b, 0x42, 0x16, 0x78, 0x73, 0x40, 0x08, 0x26, + 0x18, 0x00, 0x5b, 0x08, 0x20, 0x40, 0x00, 0xd0, 0x6b, 0x40, 0x01, 0x3e, + 0x00, 0x2e, 0xf7, 0xd1, 0x42, 0x48, 0x01, 0x32, 0x82, 0x42, 0xf0, 0xd1, + 0xa6, 0x22, 0xdb, 0x43, 0x92, 0x00, 0x8a, 0x58, 0x9a, 0x42, 0x26, 0xd1, + 0x4b, 0x69, 0x00, 0x2b, 0x23, 0xd0, 0xa7, 0x22, 0x3c, 0x4c, 0x39, 0x49, + 0x92, 0x00, 0x20, 0x00, 0x01, 0xf0, 0x8a, 0xff, 0x22, 0x69, 0xe1, 0x68, + 0xa0, 0x68, 0x00, 0xf0, 0xcf, 0xf8, 0x00, 0x28, 0x15, 0xd0, 0x80, 0x25, + 0x6d, 0x01, 0x35, 0x4b, 0x5b, 0x69, 0xb3, 0x42, 0x11, 0xd8, 0xef, 0xf3, + 0x10, 0x84, 0x72, 0xb6, 0x80, 0x21, 0xc0, 0x20, 0x49, 0x01, 0x80, 0x01, + 0x02, 0xf0, 0x66, 0xf8, 0x84, 0xf3, 0x10, 0x88, 0x00, 0x21, 0x64, 0x22, + 0x08, 0x00, 0x01, 0xf0, 0xf3, 0xfd, 0x06, 0xb0, 0x70, 0xbd, 0xa3, 0x69, + 0x01, 0x2b, 0x13, 0xd1, 0x20, 0x00, 0x1c, 0x30, 0x00, 0xf0, 0x00, 0xf9, + 0x00, 0x28, 0xf4, 0xd0, 0xe0, 0x6d, 0x00, 0xf0, 0x4f, 0xf9, 0x00, 0x28, + 0xef, 0xd0, 0x23, 0x6e, 0x00, 0x93, 0x63, 0x6e, 0x01, 0x93, 0x00, 0x9b, + 0x00, 0x2b, 0x04, 0xd1, 0x00, 0xf0, 0x9c, 0xf9, 0x01, 0x36, 0x50, 0x34, + 0xcf, 0xe7, 0x00, 0x9b, 0x02, 0x93, 0xab, 0x42, 0x00, 0xd9, 0x02, 0x95, + 0x02, 0x98, 0x00, 0xf0, 0x6b, 0xf9, 0x03, 0x90, 0x00, 0x28, 0xd8, 0xd0, + 0x2a, 0x00, 0x01, 0x99, 0x01, 0xf0, 0x4a, 0xff, 0x00, 0x28, 0x15, 0xd0, + 0xef, 0xf3, 0x10, 0x83, 0x05, 0x93, 0x72, 0xb6, 0xf0, 0x22, 0x12, 0x06, + 0x94, 0x46, 0x01, 0x9b, 0x29, 0x00, 0x63, 0x44, 0x18, 0x00, 0x04, 0x93, + 0x02, 0xf0, 0x24, 0xf8, 0x2a, 0x00, 0x03, 0x99, 0x04, 0x98, 0x02, 0xf0, + 0x5b, 0xf8, 0x05, 0x9b, 0x83, 0xf3, 0x10, 0x88, 0x00, 0x9b, 0x02, 0x9a, + 0x9b, 0x1a, 0x80, 0x22, 0x52, 0x01, 0x94, 0x46, 0x00, 0x93, 0x01, 0x9b, + 0x63, 0x44, 0x01, 0x93, 0xc5, 0xe7, 0xc0, 0x46, 0xdc, 0x23, 0x00, 0x20, + 0x00, 0x30, 0x00, 0x10, 0x20, 0x83, 0xb8, 0xed, 0x98, 0x32, 0x00, 0x10, + 0xf4, 0x26, 0x00, 0x20, 0x00, 0x20, 0x70, 0x47, 0x09, 0x4b, 0x10, 0xb5, + 0x1a, 0x68, 0x51, 0x43, 0x08, 0x4a, 0x10, 0x68, 0x40, 0x18, 0xef, 0xf3, + 0x10, 0x84, 0x72, 0xb6, 0xf0, 0x22, 0x12, 0x06, 0x19, 0x68, 0x80, 0x18, + 0x01, 0xf0, 0xf4, 0xff, 0x84, 0xf3, 0x10, 0x88, 0x00, 0x20, 0x10, 0xbd, + 0xd8, 0x25, 0x00, 0x20, 0x90, 0x29, 0x00, 0x20, 0x0a, 0x48, 0x10, 0xb5, + 0x04, 0x68, 0x4c, 0x43, 0xa4, 0x18, 0x09, 0x4a, 0x10, 0x68, 0x00, 0x19, + 0xef, 0xf3, 0x10, 0x84, 0x72, 0xb6, 0xf0, 0x22, 0x12, 0x06, 0x80, 0x18, + 0x19, 0x00, 0x02, 0x9a, 0x02, 0xf0, 0x16, 0xf8, 0x84, 0xf3, 0x10, 0x88, + 0x00, 0x20, 0x10, 0xbd, 0xd8, 0x25, 0x00, 0x20, 0x90, 0x29, 0x00, 0x20, + 0x18, 0x00, 0x06, 0x4b, 0x10, 0xb5, 0x1c, 0x68, 0x05, 0x4b, 0x4c, 0x43, + 0x19, 0x68, 0xa4, 0x18, 0x09, 0x19, 0x02, 0x9a, 0x01, 0xf0, 0xd4, 0xfe, + 0x00, 0x20, 0x10, 0xbd, 0xd8, 0x25, 0x00, 0x20, 0x90, 0x29, 0x00, 0x20, + 0x80, 0x23, 0x70, 0xb5, 0x07, 0x4d, 0x04, 0x00, 0x2a, 0x00, 0x05, 0x60, + 0x06, 0x49, 0x5b, 0x01, 0x06, 0x48, 0x01, 0xf0, 0x3b, 0xf8, 0x23, 0x68, + 0x2d, 0x18, 0x5a, 0x1c, 0x65, 0x60, 0x22, 0x60, 0x18, 0x78, 0x70, 0xbd, + 0xc8, 0x2f, 0x00, 0x20, 0xdc, 0x25, 0x00, 0x20, 0x30, 0x26, 0x00, 0x20, + 0xf8, 0xb5, 0x1d, 0x4b, 0x1d, 0x4e, 0x18, 0x60, 0x1d, 0x4b, 0x0d, 0x00, + 0x19, 0x60, 0x17, 0x00, 0x00, 0x21, 0x78, 0x22, 0x30, 0x00, 0x01, 0xf0, + 0xa3, 0xfe, 0x00, 0x23, 0x19, 0x4c, 0xa3, 0x64, 0x23, 0x60, 0x19, 0x4b, + 0xe5, 0x61, 0x63, 0x60, 0x18, 0x4b, 0xa3, 0x60, 0x18, 0x4b, 0xe3, 0x60, + 0x18, 0x4b, 0x23, 0x61, 0x80, 0x23, 0x5b, 0x00, 0x63, 0x61, 0xa3, 0x61, + 0x00, 0x2d, 0x04, 0xd0, 0x29, 0x00, 0x38, 0x00, 0x01, 0xf0, 0xd8, 0xfd, + 0x05, 0x00, 0x10, 0x23, 0x63, 0x62, 0xf0, 0x33, 0xa3, 0x62, 0xe3, 0x62, + 0x10, 0x4b, 0x30, 0x00, 0x23, 0x63, 0x10, 0x4b, 0x21, 0x00, 0x63, 0x63, + 0x0f, 0x4b, 0x25, 0x62, 0xa3, 0x63, 0x00, 0x23, 0xe3, 0x63, 0x23, 0x64, + 0x63, 0x64, 0x00, 0xf0, 0x37, 0xfe, 0xc0, 0x43, 0xc0, 0x0f, 0xf8, 0xbd, + 0x90, 0x29, 0x00, 0x20, 0x30, 0x26, 0x00, 0x20, 0xd8, 0x25, 0x00, 0x20, + 0xa8, 0x26, 0x00, 0x20, 0x4d, 0x03, 0x00, 0x20, 0x19, 0x03, 0x00, 0x20, + 0xe9, 0x02, 0x00, 0x20, 0xe5, 0x02, 0x00, 0x20, 0xca, 0xd1, 0x00, 0x20, + 0xca, 0xd0, 0x00, 0x20, 0xca, 0xd2, 0x00, 0x20, 0x00, 0x21, 0xf0, 0xb5, + 0x21, 0x4b, 0x22, 0x4f, 0x19, 0x70, 0x22, 0x4e, 0x22, 0x4b, 0x85, 0xb0, + 0x02, 0x00, 0x00, 0x93, 0x39, 0x00, 0x01, 0x23, 0x30, 0x00, 0x00, 0xf0, + 0x0f, 0xff, 0x00, 0x28, 0x03, 0xda, 0x00, 0x25, 0x28, 0x00, 0x05, 0xb0, + 0xf0, 0xbd, 0x02, 0x23, 0x39, 0x00, 0x30, 0x00, 0x03, 0xaa, 0x00, 0xf0, + 0xc1, 0xff, 0x02, 0x28, 0xf3, 0xd1, 0x39, 0x00, 0x30, 0x00, 0x01, 0xf0, + 0xc9, 0xf8, 0x6b, 0x46, 0x1b, 0x7b, 0x01, 0x25, 0x1f, 0x2b, 0xeb, 0xd1, + 0x6b, 0x46, 0x5b, 0x7b, 0x8b, 0x2b, 0xe7, 0xd1, 0x01, 0xf0, 0xf2, 0xf9, + 0x00, 0x23, 0x80, 0x22, 0x0f, 0x4c, 0x10, 0x49, 0x23, 0x60, 0x63, 0x60, + 0x0f, 0x4b, 0x20, 0x00, 0x12, 0x02, 0xa3, 0x60, 0x01, 0xf0, 0xe7, 0xf9, + 0x20, 0x00, 0x01, 0xf0, 0x5b, 0xfb, 0x00, 0x28, 0x04, 0xd0, 0x39, 0x00, + 0x30, 0x00, 0x01, 0xf0, 0xa9, 0xf8, 0xce, 0xe7, 0x01, 0x4b, 0x1d, 0x70, + 0xcc, 0xe7, 0xc0, 0x46, 0xc8, 0x50, 0x00, 0x20, 0xdc, 0x25, 0x00, 0x20, + 0x30, 0x26, 0x00, 0x20, 0x6c, 0x25, 0x00, 0x20, 0xc0, 0x2a, 0x00, 0x20, + 0xca, 0x50, 0x00, 0x20, 0x71, 0x03, 0x00, 0x20, 0xf8, 0xb5, 0x13, 0x4b, + 0x05, 0x00, 0x1c, 0x78, 0x00, 0x2c, 0x13, 0xd0, 0x80, 0x27, 0x7f, 0x01, + 0x00, 0x2d, 0x19, 0xd0, 0x0f, 0x48, 0x10, 0x4b, 0x2e, 0x00, 0x43, 0x61, + 0x83, 0x61, 0xbd, 0x42, 0x00, 0xd9, 0x3e, 0x00, 0x9b, 0x19, 0xc3, 0x61, + 0x01, 0xf0, 0xc4, 0xf9, 0x01, 0x28, 0x0d, 0xd8, 0xad, 0x1b, 0xed, 0xe7, + 0x23, 0x00, 0x02, 0x00, 0x08, 0x49, 0x09, 0x48, 0x01, 0xf0, 0x72, 0xf8, + 0x2d, 0x1a, 0x6c, 0x42, 0x6c, 0x41, 0xe4, 0xb2, 0x20, 0x00, 0xf8, 0xbd, + 0x00, 0x24, 0xfb, 0xe7, 0xc8, 0x50, 0x00, 0x20, 0xc0, 0x2a, 0x00, 0x20, + 0xc8, 0x40, 0x00, 0x20, 0xdc, 0x25, 0x00, 0x20, 0x30, 0x26, 0x00, 0x20, + 0x0d, 0x4b, 0x70, 0xb5, 0x1b, 0x78, 0x05, 0x00, 0x0c, 0x4c, 0x00, 0x2b, + 0x09, 0xd1, 0x03, 0x00, 0x22, 0x00, 0x0b, 0x49, 0x0b, 0x48, 0x00, 0xf0, + 0x49, 0xff, 0xa8, 0x42, 0x0a, 0xd1, 0x20, 0x00, 0x70, 0xbd, 0x09, 0x48, + 0x2d, 0x19, 0x44, 0x61, 0x84, 0x61, 0xc5, 0x61, 0x01, 0xf0, 0x90, 0xf9, + 0x01, 0x28, 0xf4, 0xd9, 0x00, 0x20, 0xf3, 0xe7, 0xc8, 0x50, 0x00, 0x20, + 0xc8, 0x40, 0x00, 0x20, 0xdc, 0x25, 0x00, 0x20, 0x30, 0x26, 0x00, 0x20, + 0xc0, 0x2a, 0x00, 0x20, 0x10, 0xb5, 0x02, 0x49, 0x02, 0x48, 0x00, 0xf0, + 0x25, 0xff, 0x10, 0xbd, 0xdc, 0x25, 0x00, 0x20, 0x30, 0x26, 0x00, 0x20, + 0xf7, 0xb5, 0x0c, 0x24, 0x44, 0x43, 0x1e, 0x00, 0x22, 0x4b, 0x0d, 0x00, + 0xe4, 0x18, 0x63, 0x68, 0x01, 0x92, 0xb3, 0x42, 0x00, 0xd2, 0x66, 0x60, + 0xc0, 0x23, 0x07, 0x1f, 0x9b, 0x01, 0xff, 0xb2, 0x23, 0x43, 0x01, 0x2f, + 0x26, 0xd8, 0x01, 0x2d, 0x24, 0xd1, 0x03, 0x22, 0x1a, 0x60, 0x2b, 0x00, + 0xa2, 0x68, 0x1a, 0x42, 0xfc, 0xd0, 0x01, 0x9a, 0x23, 0x68, 0x80, 0x21, + 0x52, 0x01, 0x5a, 0x40, 0xe0, 0x23, 0x49, 0x01, 0x1a, 0x40, 0x21, 0x43, + 0x0a, 0x60, 0x01, 0x2f, 0x09, 0xd8, 0x03, 0x22, 0x23, 0x68, 0x6b, 0x40, + 0x13, 0x40, 0x0b, 0x60, 0x01, 0x23, 0xab, 0x40, 0xa2, 0x68, 0x13, 0x42, + 0xfc, 0xd0, 0x80, 0x23, 0x80, 0x22, 0x9b, 0x01, 0x23, 0x43, 0x12, 0x01, + 0x01, 0x20, 0x1a, 0x60, 0x66, 0x60, 0xfe, 0xbd, 0x80, 0x22, 0x12, 0x01, + 0x1a, 0x60, 0x07, 0x4b, 0x80, 0x00, 0xc1, 0x58, 0x00, 0x29, 0xd8, 0xd0, + 0x58, 0x69, 0x01, 0xf0, 0xaf, 0xfc, 0x01, 0x30, 0x01, 0x38, 0xfd, 0xd1, + 0xd1, 0xe7, 0xc0, 0x46, 0x00, 0x80, 0x00, 0x40, 0x94, 0x2a, 0x00, 0x20, + 0x73, 0xb5, 0x0c, 0x20, 0x01, 0xf0, 0x9c, 0xfb, 0x01, 0xf0, 0xd2, 0xfa, + 0x00, 0x28, 0x0a, 0xd0, 0x00, 0x23, 0x2a, 0x4a, 0x2a, 0x48, 0x99, 0x00, + 0x01, 0x33, 0x88, 0x50, 0x0a, 0x2b, 0xfa, 0xd1, 0x28, 0x4b, 0x53, 0x62, + 0x73, 0xbd, 0x28, 0x4c, 0xa0, 0x67, 0x01, 0xf0, 0xf1, 0xfb, 0x01, 0x22, + 0x26, 0x4b, 0x1a, 0x60, 0x63, 0x6c, 0x01, 0x2b, 0xfc, 0xd1, 0x03, 0x22, + 0x24, 0x4b, 0x1a, 0x60, 0xa5, 0x6b, 0x01, 0x2d, 0xfc, 0xd1, 0x02, 0x26, + 0x05, 0x24, 0x29, 0x00, 0x06, 0x23, 0x21, 0x4a, 0x21, 0x48, 0x00, 0x96, + 0x01, 0xf0, 0x26, 0xfb, 0x23, 0x00, 0x29, 0x00, 0x1f, 0x4a, 0x20, 0x48, + 0x00, 0x94, 0x01, 0xf0, 0x1f, 0xfb, 0x80, 0x23, 0x31, 0x00, 0x00, 0x22, + 0x5b, 0x00, 0x04, 0x20, 0xff, 0xf7, 0x78, 0xff, 0x80, 0x23, 0x29, 0x00, + 0x00, 0x22, 0x20, 0x00, 0x5b, 0x00, 0xff, 0xf7, 0x71, 0xff, 0x00, 0x22, + 0x80, 0x23, 0x11, 0x00, 0x5b, 0x00, 0x07, 0x20, 0xff, 0xf7, 0x6a, 0xff, + 0x00, 0x22, 0x80, 0x23, 0x11, 0x00, 0x5b, 0x00, 0x08, 0x20, 0xff, 0xf7, + 0x63, 0xff, 0x00, 0x22, 0x80, 0x23, 0x11, 0x00, 0x9b, 0x01, 0x09, 0x20, + 0xff, 0xf7, 0x5c, 0xff, 0x00, 0x22, 0x80, 0x23, 0x11, 0x00, 0x5b, 0x00, + 0x06, 0x20, 0xff, 0xf7, 0x55, 0xff, 0xb3, 0xe7, 0x94, 0x2a, 0x00, 0x20, + 0x00, 0x6c, 0xdc, 0x02, 0x1b, 0xb7, 0x00, 0x00, 0x00, 0x80, 0x00, 0x40, + 0x3c, 0xb0, 0x00, 0x40, 0x30, 0xb0, 0x00, 0x40, 0x00, 0x2f, 0x68, 0x59, + 0x00, 0x80, 0x02, 0x40, 0x00, 0x8c, 0x86, 0x47, 0x00, 0xc0, 0x02, 0x40, + 0x83, 0x05, 0x9b, 0x15, 0x01, 0x33, 0x02, 0x00, 0x58, 0x42, 0x58, 0x41, + 0x80, 0x18, 0x80, 0x05, 0x80, 0x0d, 0x04, 0x30, 0x70, 0x47, 0x02, 0x00, + 0x83, 0x6a, 0x28, 0x32, 0x00, 0x2b, 0x03, 0xd0, 0x18, 0x68, 0x8b, 0x42, + 0x01, 0xd1, 0x10, 0x60, 0x70, 0x47, 0x1a, 0x00, 0x03, 0x00, 0xf5, 0xe7, + 0xf8, 0xb5, 0xc7, 0x69, 0x0d, 0x68, 0x08, 0x3f, 0x0e, 0x00, 0x00, 0x20, + 0xbd, 0x42, 0x15, 0xd3, 0x39, 0x00, 0x28, 0x00, 0x01, 0xf0, 0x10, 0xfc, + 0x01, 0x38, 0x01, 0xf0, 0x07, 0xfc, 0x02, 0x30, 0x80, 0x00, 0x39, 0x00, + 0x28, 0x1a, 0x01, 0xf0, 0x07, 0xfc, 0x04, 0x00, 0x01, 0xf0, 0xfe, 0xfb, + 0x67, 0x43, 0x80, 0x00, 0x28, 0x1a, 0xc0, 0x1b, 0x30, 0x60, 0x20, 0x00, + 0xf8, 0xbd, 0x00, 0x00, 0xf7, 0xb5, 0x0c, 0x00, 0x05, 0x00, 0x16, 0x00, + 0x49, 0x6b, 0x00, 0x2b, 0x03, 0xd0, 0x01, 0x2b, 0x21, 0xd1, 0x8e, 0x18, + 0x25, 0xd4, 0x2b, 0x6f, 0xb3, 0x42, 0x22, 0xd3, 0x33, 0x00, 0x8e, 0x42, + 0x17, 0xd0, 0x00, 0x91, 0xa8, 0x6e, 0x69, 0x46, 0xff, 0xf7, 0xca, 0xff, + 0x01, 0xa9, 0x07, 0x00, 0xa8, 0x6e, 0x01, 0x96, 0xff, 0xf7, 0xc4, 0xff, + 0x33, 0x00, 0x87, 0x42, 0x14, 0xd1, 0x62, 0x6c, 0x01, 0x99, 0x8a, 0x42, + 0x10, 0xd8, 0xa0, 0x6c, 0x12, 0x18, 0x91, 0x42, 0x0c, 0xd2, 0x66, 0x63, + 0xe1, 0x63, 0x18, 0x00, 0xfe, 0xbd, 0x0e, 0x00, 0x02, 0x2b, 0xdc, 0xd1, + 0xe3, 0x6a, 0xd6, 0x18, 0xd9, 0xd5, 0x16, 0x23, 0x5b, 0x42, 0xf4, 0xe7, + 0x22, 0x6b, 0x51, 0x03, 0x07, 0xd5, 0xd1, 0x02, 0x02, 0xd4, 0x01, 0x21, + 0x49, 0x42, 0x21, 0x64, 0x02, 0x49, 0x0a, 0x40, 0x22, 0x63, 0x66, 0x63, + 0xe7, 0xe7, 0xc0, 0x46, 0xff, 0xff, 0xfb, 0xff, 0xf0, 0xb5, 0x8b, 0xb0, + 0x09, 0x92, 0x02, 0x68, 0x04, 0x93, 0x0d, 0x00, 0x13, 0x6a, 0x04, 0x99, + 0x10, 0x9f, 0x08, 0x90, 0x8b, 0x42, 0x04, 0xd9, 0x12, 0x9b, 0xd2, 0x69, + 0xfb, 0x18, 0x93, 0x42, 0x21, 0xd9, 0x54, 0x20, 0x40, 0x42, 0x7f, 0xe0, + 0x04, 0x9b, 0x2a, 0x68, 0x12, 0x9c, 0x93, 0x42, 0x23, 0xd1, 0x6c, 0x68, + 0xab, 0x68, 0xe6, 0x18, 0xb7, 0x42, 0x4e, 0xd2, 0xa7, 0x42, 0x17, 0xd3, + 0x12, 0x9b, 0xf6, 0x1b, 0x9e, 0x42, 0x00, 0xd9, 0x1e, 0x00, 0xeb, 0x68, + 0x39, 0x1b, 0x59, 0x18, 0x32, 0x00, 0x11, 0x98, 0x01, 0xf0, 0x46, 0xfc, + 0x11, 0x9b, 0xbf, 0x19, 0x9b, 0x19, 0x11, 0x93, 0x12, 0x9b, 0x9b, 0x1b, + 0x12, 0x93, 0x12, 0x9b, 0x00, 0x2b, 0xdd, 0xd1, 0x18, 0x00, 0x5b, 0xe0, + 0x12, 0x9b, 0xe4, 0x1b, 0x9c, 0x42, 0x00, 0xd9, 0x1c, 0x00, 0x08, 0x9b, + 0x38, 0x00, 0x1e, 0x68, 0x73, 0x69, 0x19, 0x00, 0x03, 0x93, 0x01, 0xf0, + 0x73, 0xfb, 0x73, 0x68, 0x12, 0x9a, 0x06, 0x93, 0x09, 0x9b, 0x05, 0x91, + 0x93, 0x42, 0x22, 0xd8, 0x00, 0x29, 0x20, 0xd1, 0x13, 0x00, 0x03, 0x9a, + 0x93, 0x42, 0x1c, 0xd3, 0x11, 0x00, 0x20, 0x00, 0x01, 0xf0, 0x62, 0xfb, + 0x63, 0x1a, 0x30, 0x00, 0x05, 0x91, 0x03, 0x93, 0x00, 0x93, 0x3a, 0x00, + 0x11, 0x9b, 0x04, 0x99, 0x06, 0x9e, 0xb0, 0x47, 0x00, 0x28, 0x31, 0xd1, + 0x03, 0x9a, 0x11, 0x9b, 0x94, 0x46, 0x63, 0x44, 0x11, 0x93, 0x05, 0x9b, + 0xbf, 0x18, 0x1c, 0x1b, 0x12, 0x9b, 0x1b, 0x19, 0xc4, 0xe7, 0x12, 0x9c, + 0xcd, 0xe7, 0x04, 0x9b, 0x2b, 0x60, 0x05, 0x9b, 0xfb, 0x1a, 0x07, 0x93, + 0x6b, 0x60, 0x09, 0x9b, 0x5c, 0x1e, 0x03, 0x9b, 0xe4, 0x18, 0xe4, 0x19, + 0x19, 0x00, 0x20, 0x00, 0x01, 0xf0, 0x3a, 0xfb, 0xf3, 0x69, 0x64, 0x1a, + 0x9c, 0x42, 0x00, 0xd9, 0x1c, 0x00, 0x05, 0x9b, 0xd9, 0x1b, 0xb3, 0x6a, + 0x64, 0x18, 0x9c, 0x42, 0x00, 0xd9, 0x1c, 0x00, 0xac, 0x60, 0x00, 0x94, + 0x30, 0x00, 0xeb, 0x68, 0x07, 0x9a, 0x04, 0x99, 0x06, 0x9c, 0xa0, 0x47, + 0x00, 0x28, 0x9e, 0xd0, 0x0b, 0xb0, 0xf0, 0xbd, 0xf0, 0xb5, 0x03, 0x68, + 0x8d, 0xb0, 0x06, 0x93, 0x83, 0x68, 0x89, 0x05, 0x04, 0x00, 0x8f, 0x0d, + 0x05, 0x93, 0xbb, 0x42, 0x00, 0xd9, 0x05, 0x97, 0x00, 0x25, 0x13, 0x68, + 0x07, 0x93, 0x53, 0x68, 0x08, 0x93, 0x63, 0x68, 0x09, 0x93, 0x05, 0x9b, + 0xab, 0x42, 0x06, 0xd8, 0xa3, 0x68, 0x00, 0x20, 0xbb, 0x42, 0x21, 0xd0, + 0xbb, 0x42, 0x40, 0x41, 0x1d, 0xe0, 0x05, 0x9b, 0x5a, 0x1b, 0x16, 0x00, + 0x08, 0x2a, 0x00, 0xd9, 0x08, 0x26, 0x06, 0x99, 0x0a, 0xab, 0x08, 0x00, + 0x01, 0x93, 0x08, 0x9b, 0x02, 0x96, 0x5b, 0x19, 0x00, 0x93, 0x68, 0x30, + 0x07, 0x9b, 0xff, 0xf7, 0x3b, 0xff, 0x00, 0x28, 0x0a, 0xd1, 0x09, 0x9b, + 0x32, 0x00, 0x59, 0x19, 0x0a, 0xa8, 0x01, 0xf0, 0xad, 0xfb, 0x00, 0x28, + 0x04, 0xd0, 0xc0, 0x43, 0xc0, 0x0f, 0x01, 0x30, 0x0d, 0xb0, 0xf0, 0xbd, + 0xad, 0x19, 0xd2, 0xe7, 0x10, 0xb5, 0xe0, 0x24, 0x03, 0x68, 0xe4, 0x00, + 0x1b, 0x0d, 0x02, 0x00, 0x00, 0x20, 0x23, 0x42, 0x0d, 0xd0, 0x54, 0x68, + 0x0b, 0x68, 0x01, 0x30, 0x9c, 0x42, 0x08, 0xd0, 0x92, 0x68, 0x49, 0x68, + 0x8a, 0x42, 0x04, 0xd0, 0x8c, 0x42, 0x02, 0xd0, 0x9b, 0x1a, 0x58, 0x42, + 0x58, 0x41, 0x10, 0xbd, 0xf0, 0xb5, 0x97, 0xb0, 0x16, 0x00, 0x0d, 0x93, + 0x13, 0x68, 0x82, 0x6e, 0x07, 0x00, 0x12, 0x6a, 0x0c, 0x00, 0x93, 0x42, + 0x02, 0xd3, 0x54, 0x23, 0x5b, 0x42, 0xc3, 0xe0, 0x71, 0x68, 0x8a, 0x42, + 0xf9, 0xd9, 0x01, 0x00, 0x00, 0x22, 0x04, 0x25, 0x68, 0x31, 0x07, 0x91, + 0x10, 0xa9, 0x10, 0x92, 0x11, 0x92, 0x01, 0x91, 0x00, 0x92, 0x01, 0x00, + 0x2a, 0x00, 0x07, 0x98, 0x02, 0x95, 0xff, 0xf7, 0xf1, 0xfe, 0x03, 0x1e, + 0x04, 0x90, 0x01, 0xd0, 0x54, 0x33, 0x10, 0xd1, 0x02, 0x95, 0x00, 0x25, + 0x11, 0xab, 0x01, 0x93, 0x00, 0x95, 0x73, 0x68, 0x04, 0x22, 0x39, 0x00, + 0x07, 0x98, 0xff, 0xf7, 0xe1, 0xfe, 0x03, 0x00, 0x04, 0x90, 0xa8, 0x42, + 0x04, 0xd0, 0x54, 0x33, 0x08, 0xd0, 0x04, 0x98, 0x17, 0xb0, 0xf0, 0xbd, + 0x11, 0x9b, 0x10, 0x9a, 0x9b, 0x1a, 0xdd, 0x17, 0xed, 0x1a, 0xed, 0x0f, + 0xab, 0x00, 0x9a, 0x59, 0x22, 0x60, 0x01, 0x22, 0x55, 0x40, 0xaa, 0x00, + 0x92, 0x59, 0x0a, 0x95, 0x62, 0x60, 0x10, 0xaa, 0x9b, 0x58, 0xa3, 0x60, + 0x00, 0x23, 0xe3, 0x60, 0x02, 0x33, 0x0c, 0x93, 0x03, 0x3b, 0x04, 0x93, + 0xc5, 0x4b, 0x12, 0xaa, 0x03, 0xcb, 0x03, 0xc2, 0x21, 0x00, 0x01, 0x20, + 0x04, 0x22, 0x08, 0x31, 0x40, 0x42, 0x00, 0xf0, 0xb7, 0xfd, 0x00, 0x23, + 0x0b, 0x93, 0x08, 0x93, 0x01, 0x3b, 0x09, 0x93, 0x00, 0x23, 0x04, 0x9e, + 0x0e, 0x90, 0x05, 0x93, 0x09, 0x98, 0xff, 0xf7, 0x2d, 0xfe, 0x05, 0x9b, + 0xba, 0x6e, 0x1b, 0x18, 0x05, 0x93, 0x04, 0x23, 0x02, 0x93, 0x0f, 0xab, + 0x01, 0x93, 0x05, 0x9b, 0x39, 0x00, 0x00, 0x93, 0xd2, 0x69, 0x23, 0x68, + 0x07, 0x98, 0xff, 0xf7, 0x99, 0xfe, 0x05, 0x1e, 0x06, 0xd0, 0x2b, 0x00, + 0x54, 0x33, 0x00, 0xd0, 0x3d, 0xe1, 0x00, 0x23, 0xa3, 0x75, 0x1f, 0xe0, + 0x04, 0x22, 0x0e, 0x98, 0x0f, 0xa9, 0x00, 0xf0, 0x8d, 0xfd, 0x0f, 0x9b, + 0x09, 0x9a, 0x1b, 0xba, 0x5a, 0x40, 0x0e, 0x90, 0x06, 0x92, 0x0f, 0x92, + 0x44, 0xd5, 0x09, 0x9b, 0xe0, 0x22, 0x1e, 0x0d, 0xa0, 0x23, 0xd2, 0x00, + 0xdb, 0x00, 0x16, 0x40, 0x9e, 0x42, 0x06, 0xd1, 0xbb, 0x6e, 0xe0, 0x68, + 0x99, 0x69, 0x01, 0xf0, 0x2d, 0xfa, 0x4d, 0x42, 0x4d, 0x41, 0x01, 0x20, + 0x28, 0x40, 0xa0, 0x75, 0xe3, 0x68, 0x00, 0x2b, 0x00, 0xd1, 0x25, 0xe1, + 0x38, 0x00, 0x21, 0x00, 0x3c, 0x30, 0xff, 0xf7, 0x3d, 0xff, 0x00, 0x28, + 0x0d, 0xd0, 0xfb, 0x6b, 0x04, 0x9a, 0x1b, 0x03, 0x12, 0x03, 0x9b, 0x0d, + 0x92, 0x0d, 0x9a, 0x42, 0x00, 0xd0, 0x08, 0xe1, 0x80, 0x23, 0x04, 0x9a, + 0x1b, 0x06, 0x1a, 0x43, 0x04, 0x92, 0x1d, 0x9b, 0x00, 0x2b, 0x08, 0xd0, + 0x04, 0x9b, 0xa2, 0x8a, 0x1b, 0x03, 0x9b, 0x0d, 0x93, 0x42, 0x00, 0xd9, + 0x13, 0x00, 0x1d, 0x9a, 0x13, 0x80, 0x04, 0x9b, 0x00, 0x2b, 0x00, 0xdb, + 0x6b, 0xe7, 0x18, 0x03, 0xa3, 0x8a, 0x80, 0x0d, 0x83, 0x42, 0x00, 0xd9, + 0x0a, 0xe1, 0x00, 0x23, 0x04, 0x93, 0x62, 0xe7, 0x06, 0x98, 0xff, 0xf7, + 0xbf, 0xfd, 0xbb, 0x6e, 0xda, 0x69, 0x05, 0x9b, 0xc0, 0x18, 0x90, 0x42, + 0xa1, 0xd8, 0xe0, 0x20, 0x06, 0x9b, 0xc0, 0x00, 0x1b, 0x0d, 0xa0, 0x21, + 0x03, 0x40, 0x04, 0x20, 0xc9, 0x00, 0x09, 0x90, 0x8b, 0x42, 0x3e, 0xd1, + 0x14, 0xab, 0x01, 0x93, 0x05, 0x9b, 0x02, 0x90, 0x1b, 0x18, 0x00, 0x93, + 0x39, 0x00, 0x23, 0x68, 0x07, 0x98, 0xff, 0xf7, 0x1f, 0xfe, 0x05, 0x1e, + 0x85, 0xd1, 0x14, 0x9b, 0x0e, 0x9a, 0x93, 0x42, 0x85, 0xd1, 0x0f, 0x9b, + 0x06, 0x9a, 0x1b, 0x0d, 0xdb, 0x07, 0x5a, 0x40, 0x06, 0x92, 0x0e, 0xa9, + 0x04, 0x22, 0xf8, 0x6a, 0x00, 0xf0, 0x10, 0xfd, 0xf8, 0x62, 0x0f, 0x98, + 0xff, 0xf7, 0x8e, 0xfd, 0x05, 0x9b, 0xc0, 0x18, 0x06, 0x9b, 0xe0, 0x60, + 0x23, 0x61, 0x08, 0x9b, 0xa3, 0x82, 0x12, 0x9b, 0xa3, 0x61, 0x13, 0x9b, + 0xe3, 0x61, 0x0b, 0x9b, 0xe3, 0x75, 0x01, 0x23, 0x5b, 0x42, 0x0e, 0x93, + 0x33, 0x00, 0x06, 0x9a, 0x04, 0x96, 0x09, 0x92, 0x1e, 0x00, 0x47, 0xe7, + 0x01, 0x22, 0x0e, 0x98, 0x14, 0xa9, 0x00, 0xf0, 0xf1, 0xfc, 0x09, 0x9b, + 0x0e, 0x90, 0x01, 0x33, 0x09, 0x93, 0x0f, 0x98, 0xff, 0xf7, 0x6c, 0xfd, + 0x09, 0x9a, 0x23, 0x68, 0x90, 0x42, 0x14, 0xd9, 0x01, 0x21, 0x02, 0x91, + 0x14, 0xa9, 0x05, 0x98, 0x01, 0x91, 0x09, 0x99, 0xba, 0x6e, 0x09, 0x18, + 0x00, 0x91, 0xd2, 0x69, 0x39, 0x00, 0x07, 0x98, 0xff, 0xf7, 0xd6, 0xfd, + 0x05, 0x1e, 0xdf, 0xd0, 0x03, 0x00, 0x54, 0x33, 0x7b, 0xd1, 0x00, 0x23, + 0xa3, 0x75, 0xe0, 0x21, 0xe0, 0x20, 0x0f, 0x9b, 0xc9, 0x00, 0x1a, 0x0d, + 0xc0, 0x00, 0x11, 0x40, 0x02, 0x42, 0x1f, 0xd1, 0x08, 0x9a, 0x1b, 0x03, + 0x9b, 0x0d, 0x9a, 0x42, 0x01, 0xd8, 0x01, 0x33, 0x08, 0x93, 0x0f, 0x99, + 0x1c, 0x9b, 0x0d, 0x9a, 0x4b, 0x40, 0x1a, 0x40, 0x09, 0x92, 0x0d, 0x9a, + 0x1a, 0x42, 0x49, 0xd1, 0x23, 0x68, 0x1f, 0x98, 0x14, 0x93, 0x05, 0x9b, + 0x14, 0xaa, 0x04, 0x33, 0x15, 0x93, 0x1e, 0x9b, 0x98, 0x47, 0x05, 0x1e, + 0x3a, 0xda, 0x03, 0x00, 0x54, 0x33, 0x52, 0xd1, 0x09, 0x9b, 0x13, 0xe7, + 0x80, 0x20, 0xc0, 0x00, 0x81, 0x42, 0x19, 0xd1, 0x08, 0x99, 0x52, 0xb2, + 0x89, 0x18, 0x89, 0xb2, 0x35, 0x48, 0x08, 0x91, 0x35, 0x49, 0x30, 0x40, + 0x01, 0x43, 0x8b, 0x42, 0x03, 0xd1, 0x80, 0x23, 0x1b, 0x06, 0x1e, 0x43, + 0xd3, 0xe7, 0x71, 0x1c, 0xd1, 0xd0, 0x1b, 0x03, 0x31, 0x03, 0x9b, 0x0d, + 0x89, 0x0d, 0x8b, 0x42, 0xcb, 0xd8, 0x92, 0x02, 0x96, 0x19, 0xc8, 0xe7, + 0xc0, 0x23, 0xdb, 0x00, 0x99, 0x42, 0xc4, 0xd1, 0x01, 0x23, 0x1a, 0x40, + 0x07, 0x33, 0x02, 0x93, 0x12, 0xab, 0x01, 0x93, 0x05, 0x9b, 0x0b, 0x92, + 0x04, 0x33, 0xba, 0x6e, 0x00, 0x93, 0x39, 0x00, 0x23, 0x68, 0xd2, 0x69, + 0x07, 0x98, 0xff, 0xf7, 0x73, 0xfd, 0x54, 0x30, 0xb1, 0xd1, 0xdc, 0xe6, + 0x0f, 0x99, 0x00, 0x28, 0x03, 0xd1, 0x0e, 0x00, 0x33, 0x00, 0x04, 0x9e, + 0x6f, 0xe7, 0x33, 0x00, 0x1c, 0x4a, 0x4b, 0x40, 0x13, 0x42, 0x0b, 0xd0, + 0x02, 0x28, 0xf5, 0xd1, 0x32, 0x03, 0x0b, 0x03, 0x92, 0x0d, 0x9b, 0x0d, + 0x9a, 0x42, 0xef, 0xd3, 0x80, 0x26, 0x36, 0x06, 0x0e, 0x43, 0xeb, 0xe7, + 0x01, 0x26, 0x76, 0x42, 0xe8, 0xe7, 0x04, 0x95, 0x77, 0xe6, 0x04, 0x99, + 0x01, 0x31, 0x00, 0xd1, 0xf7, 0xe6, 0x9a, 0x42, 0x00, 0xd8, 0xf4, 0xe6, + 0x0f, 0x4a, 0x04, 0x9b, 0x94, 0x46, 0x63, 0x44, 0x04, 0x93, 0xee, 0xe6, + 0x23, 0x68, 0x62, 0x68, 0x63, 0x60, 0x0a, 0x9b, 0x22, 0x60, 0x9b, 0x00, + 0x10, 0xaa, 0x9b, 0x58, 0xa3, 0x60, 0x0c, 0x9b, 0x01, 0x2b, 0x00, 0xd1, + 0x31, 0xe6, 0x01, 0x23, 0x0c, 0x93, 0x75, 0xe6, 0x02, 0x23, 0x2d, 0xe6, + 0xf4, 0x23, 0x00, 0x20, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x4f, + 0x00, 0xfc, 0xff, 0x7f, 0x00, 0xfc, 0xff, 0xff, 0xf0, 0xb5, 0x1c, 0x00, + 0xcb, 0x68, 0x8d, 0xb0, 0x06, 0x93, 0x0b, 0x69, 0x06, 0x00, 0x3c, 0x30, + 0x0b, 0x93, 0x0f, 0x00, 0x09, 0x92, 0xff, 0xf7, 0xf3, 0xfd, 0x09, 0x9b, + 0x1b, 0x03, 0x9b, 0x0d, 0x08, 0x93, 0x00, 0x23, 0x05, 0x93, 0x98, 0x42, + 0x10, 0xd0, 0x08, 0x9b, 0x00, 0x2b, 0x0d, 0xd0, 0xf3, 0x6b, 0x1a, 0x03, + 0x23, 0x03, 0x92, 0x0d, 0x9b, 0x0d, 0x93, 0x42, 0x9b, 0x41, 0x80, 0x22, + 0xd2, 0x00, 0x13, 0x40, 0x38, 0x4a, 0x94, 0x46, 0x63, 0x44, 0x05, 0x93, + 0x0b, 0x9d, 0x28, 0x00, 0xff, 0xf7, 0x84, 0xfc, 0x06, 0x9a, 0x03, 0x1d, + 0x93, 0x42, 0x32, 0xd8, 0x06, 0x9b, 0x31, 0x00, 0x1b, 0x1a, 0x06, 0x93, + 0x33, 0x00, 0x68, 0x33, 0x07, 0x93, 0x04, 0x23, 0x02, 0x93, 0x0b, 0xab, + 0x01, 0x93, 0x06, 0x9b, 0x04, 0x22, 0x00, 0x93, 0x07, 0x98, 0x3b, 0x68, + 0xff, 0xf7, 0xea, 0xfc, 0x01, 0x1e, 0x20, 0xd1, 0x0b, 0x9b, 0x1b, 0xba, + 0x6b, 0x40, 0x5b, 0x00, 0x5b, 0x08, 0x0b, 0x93, 0x08, 0x9b, 0x00, 0x2b, + 0x1f, 0xd0, 0xe0, 0x21, 0x80, 0x22, 0x2b, 0x0d, 0xc9, 0x00, 0xd2, 0x00, + 0x19, 0x40, 0x91, 0x42, 0x17, 0xd1, 0x05, 0x9a, 0xa1, 0x1a, 0x08, 0x03, + 0x2a, 0x03, 0x80, 0x0d, 0x92, 0x0d, 0x90, 0x42, 0x0f, 0xd3, 0x1d, 0x4a, + 0x11, 0x40, 0x1d, 0x4a, 0x11, 0x43, 0xa9, 0x42, 0x04, 0xd1, 0x02, 0x21, + 0x49, 0x42, 0x08, 0x00, 0x0d, 0xb0, 0xf0, 0xbd, 0x05, 0x9a, 0x5b, 0xb2, + 0x9b, 0x02, 0x9b, 0x18, 0x05, 0x93, 0x05, 0x9b, 0x09, 0x9a, 0xe3, 0x1a, + 0x6b, 0x40, 0x1a, 0x42, 0xb4, 0xd1, 0xac, 0x05, 0xa3, 0x15, 0x01, 0x33, + 0xeb, 0xd0, 0x14, 0x9b, 0xa4, 0x0d, 0x9c, 0x42, 0x00, 0xd9, 0x1c, 0x00, + 0x13, 0x9b, 0x06, 0x9a, 0x01, 0x93, 0x12, 0x9b, 0x31, 0x00, 0x04, 0x33, + 0x9b, 0x18, 0x00, 0x93, 0x22, 0x00, 0x3b, 0x68, 0x07, 0x98, 0x02, 0x94, + 0xff, 0xf7, 0xa2, 0xfc, 0x01, 0x1e, 0xd8, 0xd1, 0x14, 0x9b, 0x1a, 0x1b, + 0x13, 0x9b, 0x18, 0x19, 0x01, 0xf0, 0x06, 0xf9, 0x05, 0x9b, 0x59, 0x19, + 0xcf, 0xe7, 0xc0, 0x46, 0x00, 0xfc, 0xff, 0xff, 0x00, 0xfc, 0x0f, 0x00, + 0x00, 0x00, 0x10, 0x40, 0x1f, 0xb5, 0x9c, 0x05, 0xa4, 0x0d, 0x02, 0x94, + 0x06, 0x9c, 0x01, 0x94, 0x00, 0x24, 0x00, 0x94, 0xff, 0xf7, 0x5c, 0xff, + 0x04, 0xb0, 0x10, 0xbd, 0xf0, 0xb5, 0x91, 0xb0, 0x0a, 0x93, 0x13, 0x68, + 0x06, 0x00, 0x06, 0x93, 0x0a, 0x9b, 0x05, 0x91, 0x0b, 0x92, 0x00, 0x2b, + 0x02, 0xd0, 0x4b, 0x4b, 0x0a, 0x9a, 0x13, 0x80, 0x32, 0x6a, 0x05, 0x9b, + 0x49, 0x4c, 0x9a, 0x61, 0x72, 0x6a, 0xda, 0x61, 0x48, 0x4d, 0x06, 0x98, + 0x29, 0x00, 0x01, 0xf0, 0x91, 0xf9, 0x06, 0x9b, 0x29, 0x00, 0x1f, 0x18, + 0x38, 0x00, 0x01, 0xf0, 0x71, 0xf9, 0x07, 0x90, 0x01, 0x28, 0x06, 0xd1, + 0x3b, 0x78, 0x2e, 0x2b, 0x0d, 0xd1, 0x07, 0x9b, 0xfb, 0x18, 0x06, 0x93, + 0xea, 0xe7, 0x07, 0x9b, 0x02, 0x2b, 0x06, 0xd1, 0x02, 0x22, 0x38, 0x00, + 0x3c, 0x49, 0x01, 0xf0, 0xcd, 0xf8, 0x00, 0x28, 0xf1, 0xd0, 0x07, 0x9b, + 0xfb, 0x18, 0x1d, 0x00, 0x06, 0x93, 0x01, 0x23, 0x08, 0x93, 0x28, 0x00, + 0x35, 0x49, 0x01, 0xf0, 0x6d, 0xf9, 0x2d, 0x18, 0x28, 0x00, 0x33, 0x49, + 0x01, 0xf0, 0x4e, 0xf9, 0x09, 0x90, 0x00, 0x28, 0x15, 0xd0, 0x02, 0x28, + 0x0d, 0xd1, 0x02, 0x22, 0x28, 0x00, 0x2f, 0x49, 0x01, 0xf0, 0xb2, 0xf8, + 0x00, 0x28, 0x06, 0xd1, 0x08, 0x9b, 0x01, 0x3b, 0x08, 0x93, 0x00, 0x2b, + 0x04, 0xd1, 0xab, 0x1c, 0xd1, 0xe7, 0x08, 0x9b, 0x01, 0x33, 0x08, 0x93, + 0x09, 0x9b, 0xed, 0x18, 0xdd, 0xe7, 0x3b, 0x78, 0x00, 0x2b, 0x3d, 0xd0, + 0x0b, 0x9b, 0x1f, 0x60, 0x23, 0x0d, 0x02, 0x2b, 0x3b, 0xd1, 0x1f, 0x4b, + 0x24, 0x03, 0xa4, 0x0d, 0x9c, 0x42, 0x25, 0xd1, 0xf0, 0x25, 0xed, 0x05, + 0x2f, 0x21, 0x38, 0x00, 0x01, 0xf0, 0xb8, 0xf8, 0x42, 0x42, 0x50, 0x41, + 0x0d, 0xaa, 0x03, 0x92, 0x1b, 0x4a, 0x0a, 0x9b, 0x07, 0x99, 0x40, 0x42, + 0x02, 0x92, 0x05, 0x9a, 0x03, 0x40, 0x0f, 0x91, 0x01, 0x93, 0x00, 0x91, + 0x2b, 0x00, 0x30, 0x00, 0x05, 0x99, 0x18, 0x32, 0x0d, 0x96, 0x0e, 0x97, + 0xff, 0xf7, 0xee, 0xfc, 0x04, 0x1e, 0x15, 0xdb, 0x00, 0x28, 0x8b, 0xd1, + 0x05, 0x9b, 0xdb, 0x7d, 0x00, 0x2b, 0xdd, 0xd1, 0x02, 0x3c, 0x0d, 0xe0, + 0x0e, 0x4b, 0xa4, 0x02, 0x1c, 0x43, 0x05, 0x9b, 0x30, 0x00, 0x18, 0x33, + 0x00, 0x93, 0x0c, 0x4a, 0x23, 0x00, 0x05, 0x99, 0xff, 0xf7, 0x5a, 0xff, + 0x04, 0x1e, 0xcb, 0xda, 0x20, 0x00, 0x11, 0xb0, 0xf0, 0xbd, 0x14, 0x24, + 0x64, 0x42, 0xf9, 0xe7, 0xff, 0x03, 0x00, 0x00, 0x00, 0xfc, 0x2f, 0x00, + 0xe5, 0x23, 0x00, 0x20, 0xe7, 0x23, 0x00, 0x20, 0x55, 0x09, 0x00, 0x20, + 0x08, 0x00, 0x00, 0x20, 0x00, 0xfc, 0x0f, 0x70, 0xf0, 0xb5, 0x04, 0x00, + 0x81, 0x66, 0x08, 0x6b, 0x99, 0xb0, 0xe0, 0x60, 0x00, 0x28, 0x03, 0xd0, + 0x4b, 0x6b, 0x00, 0x2b, 0x03, 0xd1, 0xe3, 0x61, 0x0c, 0x20, 0x40, 0x42, + 0xcd, 0xe0, 0x01, 0x25, 0x8a, 0x6a, 0xe3, 0x61, 0xff, 0x21, 0x01, 0xf0, + 0x2b, 0xf8, 0xa3, 0x6e, 0x6d, 0x42, 0x9a, 0x6a, 0xff, 0x21, 0xe0, 0x69, + 0x25, 0x60, 0x01, 0xf0, 0x23, 0xf8, 0xa3, 0x6e, 0x25, 0x61, 0x9a, 0x6b, + 0x00, 0x2a, 0x01, 0xd1, 0x62, 0x66, 0xe7, 0xe7, 0x62, 0x66, 0xda, 0x6b, + 0x00, 0x2a, 0x4a, 0xd0, 0xe2, 0x66, 0x1a, 0x6c, 0x00, 0x2a, 0x48, 0xd0, + 0x5b, 0x6c, 0x22, 0x67, 0x00, 0x2b, 0x46, 0xd0, 0x63, 0x67, 0x01, 0x23, + 0x5b, 0x42, 0x23, 0x62, 0x63, 0x62, 0x23, 0x00, 0x00, 0x25, 0x26, 0x00, + 0x3c, 0x33, 0x18, 0x00, 0x0c, 0x22, 0x29, 0x00, 0xa5, 0x62, 0xe5, 0x62, + 0x30, 0x36, 0x04, 0x93, 0x00, 0xf0, 0xfe, 0xff, 0x0c, 0x22, 0x29, 0x00, + 0x30, 0x00, 0x00, 0xf0, 0xf9, 0xff, 0x20, 0x00, 0x0c, 0x22, 0x29, 0x00, + 0x48, 0x30, 0x00, 0xf0, 0xf3, 0xff, 0x1c, 0x22, 0x29, 0x00, 0x10, 0xa8, + 0x00, 0xf0, 0xee, 0xff, 0x01, 0x23, 0x17, 0x93, 0x16, 0x9b, 0x01, 0x33, + 0x02, 0xd0, 0x17, 0x9b, 0x01, 0x33, 0x1e, 0xd1, 0x23, 0x6a, 0x01, 0x33, + 0x50, 0xd0, 0x63, 0x6a, 0x01, 0x33, 0x4d, 0xd0, 0x22, 0x6b, 0xd3, 0x0f, + 0x9b, 0x18, 0x23, 0x63, 0x04, 0x9b, 0x07, 0xce, 0x07, 0xc3, 0xa3, 0x6e, + 0xe0, 0x6a, 0x1d, 0x6a, 0x29, 0x00, 0x00, 0xf0, 0x1f, 0xff, 0x00, 0x20, + 0x61, 0x65, 0xa0, 0x65, 0xe0, 0x65, 0x25, 0x66, 0x69, 0xe0, 0xff, 0x22, + 0xb2, 0xe7, 0x3c, 0x4a, 0xb4, 0xe7, 0x3c, 0x4b, 0xb6, 0xe7, 0xa3, 0x6e, + 0x1b, 0x6a, 0x5b, 0x08, 0xab, 0x42, 0x00, 0xd8, 0x6c, 0xe0, 0x07, 0xab, + 0x03, 0x93, 0x38, 0x4b, 0x38, 0x4a, 0x02, 0x93, 0x00, 0x23, 0x08, 0x92, + 0x08, 0x22, 0x01, 0x93, 0x36, 0x4b, 0x09, 0x92, 0x00, 0x93, 0x20, 0x00, + 0x35, 0x4b, 0x16, 0xaa, 0x10, 0xa9, 0x01, 0x35, 0x07, 0x94, 0xff, 0xf7, + 0x2f, 0xfc, 0x00, 0x28, 0x47, 0xdb, 0x39, 0xd0, 0x80, 0x05, 0x80, 0x15, + 0x43, 0x1c, 0x35, 0xd0, 0x10, 0x9b, 0x0a, 0xaf, 0x23, 0x62, 0x11, 0x9b, + 0x20, 0x00, 0x05, 0x93, 0x63, 0x62, 0x2b, 0x4a, 0x2b, 0x4b, 0x00, 0x97, + 0x10, 0xa9, 0xff, 0xf7, 0x9d, 0xfe, 0x00, 0x28, 0x33, 0xdb, 0x0a, 0x9b, + 0x9a, 0xb2, 0x1b, 0x0c, 0x02, 0x2b, 0x01, 0xd0, 0x16, 0x20, 0x5c, 0xe7, + 0x00, 0x2a, 0xfb, 0xd1, 0xfb, 0x68, 0x00, 0x2b, 0x03, 0xd0, 0xe2, 0x6e, + 0x93, 0x42, 0xf5, 0xd8, 0xe3, 0x66, 0x3b, 0x69, 0x00, 0x2b, 0x03, 0xd0, + 0x22, 0x6f, 0x93, 0x42, 0xee, 0xd8, 0x23, 0x67, 0x7b, 0x69, 0x00, 0x2b, + 0x03, 0xd0, 0x62, 0x6f, 0x93, 0x42, 0xe7, 0xd8, 0x63, 0x67, 0xa3, 0x6e, + 0xba, 0x68, 0x19, 0x6a, 0x8a, 0x42, 0xe1, 0xd1, 0x7a, 0x68, 0xdb, 0x69, + 0x9a, 0x42, 0xdd, 0xd1, 0x0a, 0xab, 0x00, 0x93, 0x20, 0x00, 0x14, 0x4b, + 0x14, 0x4a, 0x10, 0xa9, 0xff, 0xf7, 0x6c, 0xfe, 0x00, 0x28, 0x04, 0xda, + 0x83, 0x1c, 0x00, 0xd1, 0x76, 0xe7, 0x19, 0xb0, 0xf0, 0xbd, 0x23, 0x6b, + 0x0a, 0x9a, 0x53, 0x40, 0x23, 0x63, 0x0b, 0x9a, 0x63, 0x6b, 0x53, 0x40, + 0x63, 0x63, 0x0c, 0x9a, 0xa3, 0x6b, 0x53, 0x40, 0xa3, 0x63, 0x67, 0xe7, + 0x54, 0x20, 0x1e, 0xe7, 0xff, 0xff, 0xff, 0x7f, 0xfe, 0x03, 0x00, 0x00, + 0x55, 0x09, 0x00, 0x20, 0xea, 0x23, 0x00, 0x20, 0x08, 0x00, 0xf0, 0x0f, + 0x00, 0xfc, 0xff, 0x7f, 0x18, 0x00, 0x10, 0x20, 0x0c, 0x00, 0xf0, 0x7f, + 0x00, 0x00, 0xf0, 0x7f, 0xf0, 0xb5, 0x0f, 0x00, 0x0b, 0x63, 0x00, 0x23, + 0x89, 0xb0, 0x07, 0x92, 0x0e, 0x9a, 0x08, 0x37, 0x0a, 0x65, 0x4b, 0x63, + 0xcb, 0x63, 0xcb, 0x64, 0x0c, 0x00, 0x0b, 0x1d, 0x07, 0xaa, 0x39, 0x00, + 0x06, 0x00, 0xff, 0xf7, 0x3d, 0xfe, 0x05, 0x1e, 0x08, 0xda, 0x83, 0x1c, + 0x61, 0xd1, 0x4a, 0x4b, 0xa2, 0x88, 0x9a, 0x42, 0x02, 0xd1, 0x02, 0x25, + 0x6d, 0x42, 0x5a, 0xe0, 0x01, 0x23, 0xa3, 0x71, 0xb3, 0x6a, 0x23, 0x60, + 0xb4, 0x62, 0xab, 0x1c, 0xf5, 0xd0, 0x6d, 0x00, 0x6d, 0x0d, 0x01, 0x2d, + 0x00, 0xd0, 0x7c, 0xe0, 0xa2, 0x88, 0x41, 0x4b, 0x92, 0x02, 0x13, 0x43, + 0x22, 0x00, 0x28, 0x32, 0x00, 0x92, 0x39, 0x00, 0x30, 0x00, 0x3e, 0x4a, + 0xff, 0xf7, 0x0e, 0xfe, 0x03, 0x90, 0x00, 0x28, 0x00, 0xda, 0x6e, 0xe0, + 0x00, 0x23, 0x05, 0x95, 0x04, 0x93, 0x23, 0x6d, 0x04, 0x9a, 0x99, 0x68, + 0x8a, 0x42, 0x14, 0xd3, 0x18, 0x68, 0xe0, 0x64, 0x00, 0x28, 0x37, 0xd0, + 0xb3, 0x6e, 0xff, 0x21, 0x9a, 0x6a, 0x00, 0xf0, 0xf5, 0xfe, 0x01, 0x23, + 0x5b, 0x42, 0x23, 0x64, 0x31, 0x4a, 0x03, 0x9b, 0x1b, 0x0d, 0x93, 0x42, + 0x2c, 0xd0, 0x00, 0x25, 0x28, 0x00, 0x09, 0xb0, 0xf0, 0xbd, 0x22, 0x6b, + 0x05, 0x99, 0x0a, 0x42, 0x03, 0xd1, 0x04, 0x9b, 0x01, 0x33, 0x04, 0x93, + 0xdd, 0xe7, 0x0c, 0x22, 0xc0, 0x20, 0x04, 0x99, 0x5b, 0x68, 0x4a, 0x43, + 0x9a, 0x18, 0xa3, 0x88, 0x91, 0x68, 0x9b, 0x02, 0x0b, 0x43, 0x11, 0x78, + 0x80, 0x00, 0x52, 0x68, 0x09, 0x18, 0x09, 0x05, 0x0b, 0x43, 0x00, 0x92, + 0x39, 0x00, 0x30, 0x00, 0x20, 0x4a, 0xff, 0xf7, 0xcf, 0xfd, 0x05, 0x1e, + 0xe3, 0xda, 0x83, 0x1c, 0xe1, 0xd0, 0x21, 0x00, 0x30, 0x00, 0xff, 0xf7, + 0xe6, 0xf9, 0xd5, 0xe7, 0x0c, 0x25, 0x9b, 0xe7, 0x03, 0x9b, 0x21, 0x6b, + 0x98, 0x05, 0x80, 0x23, 0x5b, 0x03, 0x0b, 0x43, 0x23, 0x63, 0x00, 0x23, + 0x02, 0x22, 0x63, 0x64, 0xb3, 0x6e, 0x52, 0x42, 0x9b, 0x6a, 0x80, 0x0d, + 0xa2, 0x62, 0xe0, 0x62, 0x22, 0x64, 0xa3, 0x64, 0xbf, 0xd0, 0xa2, 0x88, + 0x10, 0x49, 0x92, 0x02, 0x8b, 0x42, 0x00, 0xd9, 0x0b, 0x00, 0x13, 0x43, + 0x80, 0x22, 0x92, 0x05, 0x13, 0x43, 0xe2, 0x6c, 0x39, 0x00, 0x00, 0x92, + 0x30, 0x00, 0x07, 0x4a, 0xff, 0xf7, 0xa0, 0xfd, 0x05, 0x1e, 0xac, 0xda, + 0xd1, 0xe7, 0x15, 0x25, 0x72, 0xe7, 0x03, 0x9d, 0xcd, 0xe7, 0xc0, 0x46, + 0xff, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x20, 0x00, 0xfc, 0x0f, 0x70, + 0x01, 0x02, 0x00, 0x00, 0x00, 0xfc, 0xff, 0x7f, 0xfe, 0x03, 0x00, 0x00, + 0x10, 0xb5, 0xff, 0xf7, 0xa8, 0xf9, 0x00, 0x20, 0x10, 0xbd, 0x00, 0x00, + 0xf0, 0xb5, 0x97, 0xb0, 0x0c, 0x00, 0x0a, 0x92, 0x4a, 0x6b, 0xc9, 0x6a, + 0x07, 0x00, 0x00, 0x20, 0x8a, 0x42, 0x00, 0xd3, 0xe4, 0xe0, 0x8a, 0x1a, + 0x08, 0x92, 0x9a, 0x42, 0x00, 0xd9, 0x08, 0x93, 0x08, 0x9b, 0x06, 0x93, + 0x06, 0x9b, 0x00, 0x2b, 0x01, 0xd1, 0x08, 0x98, 0xd8, 0xe0, 0x80, 0x22, + 0x23, 0x6b, 0xd2, 0x02, 0xb8, 0x6e, 0x13, 0x42, 0x03, 0xd0, 0xe2, 0x6b, + 0xc1, 0x69, 0x8a, 0x42, 0x13, 0xd1, 0x80, 0x21, 0x49, 0x03, 0x62, 0x6b, + 0x0b, 0x42, 0x79, 0xd1, 0xa1, 0x6a, 0xe3, 0x6a, 0x13, 0x91, 0x14, 0x92, + 0x00, 0x2b, 0x3b, 0xd1, 0x01, 0x22, 0x52, 0x42, 0xa2, 0x63, 0xe3, 0x63, + 0x80, 0x23, 0x22, 0x6b, 0xdb, 0x02, 0x13, 0x43, 0x23, 0x63, 0xbb, 0x6e, + 0xe6, 0x6b, 0xdb, 0x69, 0x06, 0x9a, 0x09, 0x93, 0x9b, 0x1b, 0x05, 0x93, + 0x93, 0x42, 0x00, 0xd9, 0x05, 0x92, 0x80, 0x22, 0x23, 0x6b, 0x52, 0x03, + 0x13, 0x42, 0x00, 0xd1, 0xac, 0xe0, 0x23, 0x00, 0x08, 0x33, 0x10, 0x93, + 0xa3, 0x88, 0x5e, 0x4a, 0x9b, 0x02, 0x1a, 0x43, 0x05, 0x9b, 0x11, 0x92, + 0x09, 0x9a, 0xf3, 0x18, 0x9a, 0x42, 0x00, 0xd2, 0xaf, 0xe0, 0x0a, 0x9b, + 0x0b, 0x93, 0x05, 0x9b, 0x07, 0x93, 0x07, 0x9b, 0x00, 0x2b, 0x4a, 0xd1, + 0x05, 0x9a, 0x63, 0x6b, 0x94, 0x46, 0x9b, 0x18, 0x63, 0x63, 0xe3, 0x6b, + 0x9b, 0x18, 0xe3, 0x63, 0x0a, 0x9b, 0x63, 0x44, 0x0a, 0x93, 0x06, 0x9b, + 0x9b, 0x1a, 0xa8, 0xe7, 0x22, 0x00, 0x01, 0x3b, 0x40, 0x32, 0x15, 0xa9, + 0x09, 0x92, 0x15, 0x93, 0xff, 0xf7, 0x42, 0xf9, 0x14, 0xa9, 0x06, 0x00, + 0xb8, 0x6e, 0xff, 0xf7, 0x3d, 0xf9, 0x05, 0x90, 0x13, 0x9b, 0x07, 0x93, + 0x05, 0x9b, 0xb3, 0x42, 0x03, 0xd3, 0x07, 0x9b, 0xa3, 0x63, 0x14, 0x9b, + 0xaf, 0xe7, 0x05, 0x9b, 0xf0, 0x1a, 0x00, 0xf0, 0x39, 0xfd, 0x05, 0x00, + 0x30, 0x00, 0x00, 0xf0, 0x3b, 0xfd, 0x20, 0x23, 0x5d, 0x1b, 0x01, 0x3d, + 0x85, 0x42, 0x00, 0xd9, 0x05, 0x00, 0x04, 0x23, 0x38, 0x00, 0x02, 0x93, + 0x13, 0xab, 0x01, 0x93, 0xab, 0x00, 0x00, 0x93, 0x04, 0x22, 0x07, 0x9b, + 0x09, 0x99, 0x68, 0x30, 0xff, 0xf7, 0x7c, 0xf9, 0x00, 0x28, 0x53, 0xd1, + 0x01, 0x23, 0xab, 0x40, 0xf6, 0x1a, 0xd5, 0xe7, 0x02, 0x23, 0x5b, 0x42, + 0xa3, 0x63, 0xe2, 0x63, 0x8a, 0xe7, 0xe3, 0x6c, 0x0f, 0x93, 0x23, 0x6c, + 0x02, 0x33, 0x19, 0xd1, 0x61, 0x6c, 0xa3, 0x6c, 0xcd, 0x18, 0xae, 0x42, + 0x14, 0xd2, 0x8e, 0x42, 0x12, 0xd3, 0x07, 0x9b, 0xad, 0x1b, 0x9d, 0x42, + 0x00, 0xd9, 0x1d, 0x00, 0x0f, 0x9b, 0x71, 0x1a, 0x59, 0x18, 0x2a, 0x00, + 0x0b, 0x98, 0x00, 0xf0, 0xcb, 0xfd, 0x0b, 0x9b, 0x76, 0x19, 0x5b, 0x19, + 0x0b, 0x93, 0x07, 0x9b, 0x5b, 0x1b, 0x91, 0xe7, 0x02, 0x23, 0x5b, 0x42, + 0x23, 0x64, 0xbb, 0x6e, 0x30, 0x00, 0x0d, 0x93, 0x5b, 0x69, 0x19, 0x00, + 0x0c, 0x93, 0x00, 0xf0, 0xff, 0xfc, 0x73, 0x1a, 0x0c, 0x9a, 0x0e, 0x93, + 0x63, 0x64, 0x09, 0x9b, 0x11, 0x00, 0x9d, 0x18, 0x01, 0x3d, 0xad, 0x19, + 0x28, 0x00, 0x00, 0xf0, 0xf3, 0xfc, 0x0d, 0x9b, 0x6d, 0x1a, 0x9b, 0x6a, + 0x9d, 0x42, 0x00, 0xd9, 0x1d, 0x00, 0x0f, 0x9b, 0x38, 0x00, 0x01, 0x93, + 0x0e, 0x9b, 0x11, 0x4a, 0x00, 0x93, 0x10, 0x99, 0x11, 0x9b, 0xa5, 0x64, + 0x02, 0x95, 0xff, 0xf7, 0xff, 0xfb, 0x00, 0x28, 0x00, 0xdb, 0x66, 0xe7, + 0x17, 0xb0, 0xf0, 0xbd, 0x21, 0x00, 0x38, 0x00, 0x05, 0x9b, 0x09, 0x9a, + 0x02, 0x93, 0x0a, 0x9b, 0x00, 0x96, 0x01, 0x93, 0x40, 0x31, 0xa3, 0x6b, + 0x68, 0x30, 0xff, 0xf7, 0x17, 0xf9, 0x00, 0x28, 0x00, 0xd1, 0x57, 0xe7, + 0xec, 0xe7, 0x54, 0x20, 0x40, 0x42, 0xe9, 0xe7, 0x00, 0x00, 0x10, 0x20, + 0x00, 0xfc, 0xf7, 0xff, 0x10, 0xb5, 0xff, 0xf7, 0xc5, 0xf8, 0x10, 0xbd, + 0x00, 0x23, 0x10, 0xb5, 0x1a, 0x00, 0xff, 0xf7, 0xbf, 0xf8, 0x00, 0x28, + 0x00, 0xdd, 0x00, 0x20, 0x10, 0xbd, 0x00, 0x00, 0x70, 0xb5, 0x0f, 0x25, + 0x0a, 0x4c, 0x8a, 0x18, 0x91, 0x42, 0x00, 0xd1, 0x70, 0xbd, 0x0b, 0x78, + 0x06, 0x09, 0x58, 0x40, 0x28, 0x40, 0x80, 0x00, 0x00, 0x59, 0x1b, 0x09, + 0x46, 0x40, 0x73, 0x40, 0x2b, 0x40, 0x9b, 0x00, 0x1b, 0x59, 0x30, 0x09, + 0x58, 0x40, 0x01, 0x31, 0xec, 0xe7, 0xc0, 0x46, 0xfc, 0x23, 0x00, 0x20, + 0xf0, 0xb5, 0x04, 0x00, 0x03, 0x00, 0x00, 0x25, 0x89, 0xb0, 0x20, 0x34, + 0x1d, 0x80, 0x02, 0x33, 0xa3, 0x42, 0xfb, 0xd1, 0x0b, 0x00, 0x56, 0x18, + 0x9e, 0x42, 0x0e, 0xd1, 0x00, 0x23, 0x1c, 0x00, 0x03, 0x80, 0x6d, 0x46, + 0x5c, 0x53, 0xc5, 0x5a, 0x02, 0x33, 0x64, 0x19, 0x20, 0x2b, 0xf8, 0xd1, + 0x00, 0x24, 0xa2, 0x42, 0x08, 0xd1, 0x09, 0xb0, 0xf0, 0xbd, 0x1c, 0x78, + 0x01, 0x33, 0x64, 0x00, 0x05, 0x5b, 0x01, 0x35, 0x05, 0x53, 0xe7, 0xe7, + 0x0d, 0x5d, 0x00, 0x2d, 0x08, 0xd0, 0x6b, 0x46, 0x6f, 0x46, 0x6d, 0x00, + 0x5b, 0x5b, 0x5e, 0x1c, 0x10, 0x33, 0x5b, 0x00, 0x7e, 0x53, 0x1c, 0x52, + 0x01, 0x34, 0xe6, 0xe7, 0x03, 0x68, 0x42, 0x68, 0x10, 0xb5, 0x93, 0x42, + 0x03, 0xd2, 0x5a, 0x1c, 0x02, 0x60, 0x18, 0x78, 0x10, 0xbd, 0x83, 0x68, + 0x84, 0x1d, 0x00, 0x2b, 0x07, 0xd0, 0xe2, 0x7f, 0x00, 0x2a, 0x04, 0xd1, + 0x98, 0x47, 0x00, 0x28, 0x01, 0xdb, 0xc0, 0xb2, 0xf2, 0xe7, 0x01, 0x23, + 0x00, 0x20, 0xe3, 0x77, 0xee, 0xe7, 0x03, 0x69, 0x10, 0xb5, 0x5a, 0x1e, + 0x04, 0x00, 0x02, 0x61, 0x00, 0x2b, 0x04, 0xd1, 0xff, 0xf7, 0xde, 0xff, + 0x07, 0x23, 0xe0, 0x60, 0x23, 0x61, 0xe0, 0x68, 0x43, 0x08, 0xe3, 0x60, + 0x01, 0x23, 0x18, 0x40, 0x10, 0xbd, 0xf7, 0xb5, 0x00, 0x25, 0x06, 0x00, + 0x01, 0x92, 0xa9, 0x42, 0x04, 0xd0, 0x01, 0x24, 0x27, 0x00, 0x8f, 0x40, + 0xbc, 0x42, 0x02, 0xd3, 0x01, 0x9b, 0x58, 0x19, 0xfe, 0xbd, 0x30, 0x00, + 0xff, 0xf7, 0xdd, 0xff, 0x00, 0x28, 0x00, 0xd0, 0x2d, 0x19, 0x64, 0x00, + 0xf2, 0xe7, 0xf7, 0xb5, 0x00, 0x25, 0x0b, 0x00, 0x0e, 0x00, 0x2c, 0x00, + 0x20, 0x33, 0x01, 0x90, 0x8f, 0x1c, 0x00, 0x93, 0x01, 0x98, 0xff, 0xf7, + 0xcc, 0xff, 0x00, 0x9b, 0x6d, 0x00, 0x28, 0x18, 0x9f, 0x42, 0x0b, 0xd0, + 0x3d, 0x88, 0x02, 0x37, 0x2a, 0x19, 0x45, 0x1b, 0x04, 0xd5, 0x24, 0x18, + 0x10, 0x34, 0x64, 0x00, 0xa0, 0x5b, 0xfe, 0xbd, 0x14, 0x00, 0xeb, 0xe7, + 0x03, 0x20, 0x40, 0x42, 0xf9, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0xd5, 0xb0, + 0x03, 0x92, 0x02, 0x22, 0x0e, 0x00, 0xff, 0x32, 0x05, 0x21, 0x05, 0x00, + 0xff, 0xf7, 0xbf, 0xff, 0x01, 0x22, 0x05, 0x21, 0x00, 0x90, 0x28, 0x00, + 0xff, 0xf7, 0xb9, 0xff, 0x04, 0x22, 0x01, 0x90, 0x11, 0x00, 0x28, 0x00, + 0xff, 0xf7, 0xb3, 0xff, 0x00, 0x23, 0x07, 0x00, 0x1a, 0x00, 0x04, 0xa9, + 0x5a, 0x54, 0x01, 0x33, 0x13, 0x2b, 0xfa, 0xd1, 0x00, 0x24, 0xbc, 0x42, + 0x1c, 0xd1, 0x13, 0x22, 0x30, 0x00, 0x04, 0xa9, 0xff, 0xf7, 0x46, 0xff, + 0x01, 0x9a, 0x00, 0x24, 0x94, 0x46, 0x00, 0x9b, 0x63, 0x44, 0x02, 0x93, + 0x02, 0x9b, 0x9c, 0x42, 0x19, 0xd3, 0x30, 0x00, 0x00, 0x9a, 0x04, 0xa9, + 0xff, 0xf7, 0x38, 0xff, 0x00, 0x9b, 0x04, 0xaa, 0x9b, 0x18, 0x03, 0x98, + 0x19, 0x00, 0x01, 0x9a, 0xff, 0xf7, 0x30, 0xff, 0x00, 0x20, 0x1a, 0xe0, + 0x00, 0x22, 0x03, 0x21, 0x28, 0x00, 0xff, 0xf7, 0x86, 0xff, 0x1b, 0x4b, + 0x04, 0xaa, 0xe3, 0x5c, 0x01, 0x34, 0xd0, 0x54, 0xd5, 0xe7, 0x31, 0x00, + 0x28, 0x00, 0xff, 0xf7, 0x92, 0xff, 0x00, 0x28, 0x09, 0xdb, 0x11, 0x28, + 0x21, 0xd0, 0x12, 0x28, 0x23, 0xd0, 0x10, 0x28, 0x19, 0xd1, 0x00, 0x2c, + 0x03, 0xd1, 0x03, 0x20, 0x40, 0x42, 0x55, 0xb0, 0xf0, 0xbd, 0x03, 0x22, + 0x02, 0x21, 0x54, 0xab, 0x1b, 0x19, 0x42, 0x3b, 0xff, 0x3b, 0x1f, 0x78, + 0x28, 0x00, 0xff, 0xf7, 0x64, 0xff, 0x02, 0x9b, 0x20, 0x18, 0x98, 0x42, + 0xed, 0xd8, 0xa0, 0x42, 0xc0, 0xd0, 0x04, 0xab, 0xe7, 0x54, 0x01, 0x34, + 0xf9, 0xe7, 0x04, 0xab, 0x18, 0x55, 0x01, 0x34, 0xb8, 0xe7, 0x03, 0x22, + 0x11, 0x00, 0x00, 0x27, 0xea, 0xe7, 0x0b, 0x22, 0x07, 0x21, 0xfa, 0xe7, + 0x3c, 0x24, 0x00, 0x20, 0x70, 0x47, 0x00, 0x23, 0x10, 0xb5, 0x84, 0x1d, + 0xe3, 0x77, 0x01, 0x24, 0x64, 0x42, 0x03, 0x61, 0xc3, 0x62, 0x84, 0x62, + 0xc2, 0x63, 0x81, 0x63, 0x03, 0x64, 0x03, 0x63, 0x10, 0xbd, 0x00, 0x00, + 0xf7, 0xb5, 0x80, 0x26, 0x04, 0x00, 0x76, 0x00, 0xa3, 0x6a, 0x01, 0x33, + 0x00, 0xd0, 0x93, 0xe0, 0x20, 0x00, 0xa5, 0x6a, 0xff, 0xf7, 0x1f, 0xff, + 0x00, 0x22, 0xe0, 0x62, 0x02, 0x21, 0x20, 0x00, 0xff, 0xf7, 0x2b, 0xff, + 0xa0, 0x62, 0x01, 0x28, 0x79, 0xd1, 0x01, 0x2d, 0x63, 0xd0, 0x21, 0x00, + 0x00, 0x23, 0x08, 0x31, 0xa2, 0x1d, 0xd3, 0x87, 0x02, 0x31, 0x8b, 0x87, + 0xcb, 0x87, 0x02, 0x31, 0xcb, 0x87, 0x02, 0x31, 0xcb, 0x87, 0x40, 0x31, + 0x0b, 0x80, 0x4b, 0x80, 0x23, 0x00, 0x18, 0x21, 0x52, 0x33, 0x19, 0x80, + 0x80, 0x31, 0x59, 0x80, 0x28, 0x39, 0x99, 0x80, 0x21, 0x00, 0x33, 0x00, + 0x18, 0x30, 0x64, 0x31, 0xff, 0x30, 0x0b, 0x80, 0x01, 0x33, 0x9b, 0xb2, + 0x02, 0x31, 0x83, 0x42, 0xf9, 0xd1, 0x20, 0x00, 0x00, 0x23, 0x94, 0x30, + 0x59, 0x00, 0x43, 0x52, 0x01, 0x33, 0x90, 0x2b, 0xfa, 0xd1, 0xd7, 0x21, + 0x8c, 0x20, 0x49, 0x00, 0x40, 0x00, 0x50, 0x52, 0x1a, 0x20, 0x02, 0x31, + 0xff, 0x30, 0x50, 0x52, 0x02, 0x31, 0x01, 0x30, 0x50, 0x52, 0x1c, 0x20, + 0x02, 0x31, 0xff, 0x30, 0x50, 0x52, 0x02, 0x31, 0x01, 0x30, 0x50, 0x52, + 0x1e, 0x20, 0x02, 0x31, 0xff, 0x30, 0x50, 0x52, 0x02, 0x31, 0x01, 0x30, + 0x50, 0x52, 0x20, 0x20, 0x02, 0x31, 0xff, 0x30, 0x50, 0x52, 0x22, 0x00, + 0xc5, 0x32, 0xff, 0x32, 0x13, 0x80, 0x01, 0x33, 0x9b, 0xb2, 0x02, 0x32, + 0xb3, 0x42, 0xf9, 0xd1, 0xa9, 0x22, 0x00, 0x23, 0x20, 0x21, 0x92, 0x00, + 0xa3, 0x52, 0xa2, 0x18, 0x51, 0x81, 0x53, 0x80, 0x93, 0x80, 0xd3, 0x80, + 0x13, 0x81, 0xb1, 0x22, 0x92, 0x00, 0xa1, 0x18, 0x5a, 0x00, 0x8b, 0x52, + 0x01, 0x33, 0x20, 0x2b, 0xfa, 0xd1, 0x23, 0x6b, 0x00, 0x2b, 0x00, 0xd0, + 0x8b, 0xe0, 0x21, 0x00, 0x20, 0x00, 0x44, 0x31, 0xff, 0xf7, 0xcf, 0xfe, + 0xa3, 0x1d, 0xdb, 0x7f, 0x00, 0x2b, 0x19, 0xd1, 0xff, 0x28, 0x57, 0xdc, + 0xa3, 0x69, 0xc0, 0xb2, 0x5a, 0x1c, 0xa2, 0x61, 0x3d, 0xe0, 0x02, 0x28, + 0x0a, 0xd1, 0xa9, 0x23, 0x21, 0x00, 0x9b, 0x00, 0x20, 0x00, 0xe2, 0x18, + 0x44, 0x31, 0xff, 0xf7, 0xdb, 0xfe, 0x00, 0x28, 0x00, 0xd0, 0xa7, 0xe0, + 0xa3, 0x6a, 0x00, 0x2b, 0x05, 0xd0, 0x01, 0x3b, 0x01, 0x2b, 0xd8, 0xd9, + 0x03, 0x20, 0x40, 0x42, 0x9e, 0xe0, 0x27, 0x6b, 0x00, 0x2f, 0x19, 0xd1, + 0x20, 0x00, 0xff, 0xf7, 0x67, 0xfe, 0x05, 0x00, 0x20, 0x00, 0xff, 0xf7, + 0x63, 0xfe, 0x00, 0x02, 0x45, 0x19, 0x20, 0x00, 0xff, 0xf7, 0x5e, 0xfe, + 0x01, 0x90, 0x20, 0x00, 0xff, 0xf7, 0x5a, 0xfe, 0x01, 0x9b, 0x00, 0x02, + 0xc0, 0x18, 0x46, 0x4b, 0x58, 0x40, 0x85, 0x42, 0xe2, 0xd1, 0x01, 0x35, + 0x25, 0x63, 0x27, 0x61, 0x23, 0x6b, 0x01, 0x3b, 0x23, 0x63, 0x00, 0x2b, + 0x77, 0xd0, 0x20, 0x00, 0xff, 0xf7, 0x48, 0xfe, 0xa3, 0x69, 0x5a, 0x1c, + 0xa2, 0x61, 0x18, 0x70, 0xa2, 0x6b, 0x00, 0x2a, 0x09, 0xd0, 0x23, 0x6c, + 0x59, 0x1c, 0x21, 0x64, 0xd0, 0x54, 0x23, 0x6c, 0xe2, 0x6b, 0x93, 0x42, + 0x01, 0xd1, 0x00, 0x23, 0x23, 0x64, 0xa3, 0x69, 0xe2, 0x69, 0x93, 0x42, + 0x00, 0xd2, 0x23, 0xe7, 0x00, 0x20, 0x61, 0xe0, 0xb0, 0x42, 0x5a, 0xd0, + 0x02, 0x38, 0xff, 0x38, 0x1c, 0x28, 0xb9, 0xdc, 0x30, 0x4b, 0x42, 0x00, + 0xd2, 0x5a, 0x30, 0x4b, 0x19, 0x5c, 0x20, 0x00, 0xff, 0xf7, 0x4d, 0xfe, + 0xa9, 0x23, 0x9b, 0x00, 0x20, 0x63, 0xe1, 0x18, 0x20, 0x00, 0xff, 0xf7, + 0x5c, 0xfe, 0x1d, 0x28, 0xa8, 0xdc, 0x2a, 0x4b, 0x42, 0x00, 0xd2, 0x5a, + 0x29, 0x4b, 0x19, 0x5c, 0x20, 0x00, 0xff, 0xf7, 0x3c, 0xfe, 0xa3, 0x6b, + 0x00, 0x2b, 0x2c, 0xd0, 0xe3, 0x6b, 0x98, 0x42, 0x3d, 0xd8, 0x22, 0x6c, + 0x10, 0x1a, 0x24, 0xd4, 0x60, 0x63, 0xa1, 0x6b, 0xa3, 0x69, 0x62, 0x6b, + 0x00, 0x29, 0x28, 0xd0, 0x58, 0x1c, 0xa0, 0x61, 0x8a, 0x5c, 0x1a, 0x70, + 0xa3, 0x6b, 0x00, 0x2b, 0x0b, 0xd0, 0x22, 0x6c, 0x51, 0x1c, 0x21, 0x64, + 0x61, 0x6b, 0x59, 0x5c, 0x99, 0x54, 0x23, 0x6c, 0xe2, 0x6b, 0x93, 0x42, + 0x01, 0xd1, 0x00, 0x23, 0x23, 0x64, 0x63, 0x6b, 0xe2, 0x6b, 0x01, 0x33, + 0x63, 0x63, 0x93, 0x42, 0x01, 0xd1, 0x00, 0x23, 0x63, 0x63, 0x23, 0x6b, + 0x01, 0x3b, 0x23, 0x63, 0xab, 0xe7, 0x18, 0x18, 0xd8, 0xe7, 0xa3, 0x69, + 0x62, 0x69, 0x9b, 0x1a, 0x98, 0x42, 0x00, 0xd9, 0x6a, 0xe7, 0x40, 0x42, + 0xd0, 0xe7, 0x9a, 0x5c, 0x1a, 0x70, 0xa3, 0x69, 0x01, 0x33, 0xa3, 0x61, + 0xeb, 0xe7, 0xe3, 0x6a, 0x00, 0x2b, 0x00, 0xd1, 0xc4, 0xe6, 0x01, 0x20, + 0xfe, 0xbd, 0x05, 0x20, 0x5b, 0xe7, 0xc0, 0x46, 0xff, 0xff, 0x00, 0x00, + 0xaa, 0x24, 0x00, 0x20, 0xe6, 0x24, 0x00, 0x20, 0x50, 0x24, 0x00, 0x20, + 0x8c, 0x24, 0x00, 0x20, 0x70, 0xb5, 0x05, 0x00, 0x0c, 0x00, 0x01, 0x3c, + 0x00, 0xd2, 0x70, 0xbd, 0x28, 0x00, 0xff, 0xf7, 0xb7, 0xfd, 0xf8, 0xe7, + 0x70, 0xb5, 0x04, 0x00, 0xff, 0xf7, 0xb2, 0xfd, 0x05, 0x00, 0x20, 0x00, + 0xff, 0xf7, 0xae, 0xfd, 0x00, 0x02, 0x28, 0x43, 0x80, 0xb2, 0x70, 0xbd, + 0x70, 0xb5, 0x04, 0x00, 0xff, 0xf7, 0xa6, 0xfd, 0x06, 0x00, 0x1f, 0x28, + 0x02, 0xd0, 0x03, 0x20, 0x40, 0x42, 0x70, 0xbd, 0x20, 0x00, 0xff, 0xf7, + 0x9d, 0xfd, 0x8b, 0x28, 0xf7, 0xd1, 0x20, 0x00, 0xff, 0xf7, 0x98, 0xfd, + 0x08, 0x28, 0xf2, 0xd1, 0x20, 0x00, 0xff, 0xf7, 0x93, 0xfd, 0x03, 0x00, + 0xb3, 0x43, 0xdb, 0xb2, 0x05, 0x00, 0x00, 0x2b, 0xe9, 0xd1, 0x06, 0x21, + 0x20, 0x00, 0xff, 0xf7, 0xc9, 0xff, 0x6b, 0x07, 0x06, 0xd5, 0x20, 0x00, + 0xff, 0xf7, 0xce, 0xff, 0x01, 0x00, 0x20, 0x00, 0xff, 0xf7, 0xc0, 0xff, + 0x2b, 0x07, 0x04, 0xd5, 0x20, 0x00, 0xff, 0xf7, 0x7b, 0xfd, 0x00, 0x28, + 0xfa, 0xd1, 0xeb, 0x06, 0x04, 0xd5, 0x20, 0x00, 0xff, 0xf7, 0x74, 0xfd, + 0x00, 0x28, 0xfa, 0xd1, 0x02, 0x26, 0x35, 0x42, 0x02, 0xd0, 0x20, 0x00, + 0xff, 0xf7, 0xb6, 0xff, 0x63, 0x1d, 0xde, 0x77, 0x01, 0x23, 0x5b, 0x42, + 0x00, 0x20, 0x23, 0x62, 0xc3, 0xe7, 0x00, 0x00, 0x02, 0x4b, 0x18, 0x68, + 0x80, 0x07, 0xc0, 0x0f, 0x70, 0x47, 0xc0, 0x46, 0x00, 0xc0, 0x06, 0x40, + 0x14, 0x23, 0x10, 0xb5, 0x01, 0x00, 0x18, 0x88, 0x04, 0x33, 0x1b, 0x88, + 0x98, 0x47, 0x10, 0xbd, 0x16, 0x23, 0x10, 0xb5, 0x01, 0x00, 0x18, 0x88, + 0x02, 0x33, 0x1b, 0x88, 0x98, 0x47, 0x10, 0xbd, 0x70, 0xb5, 0x04, 0x00, + 0x01, 0x26, 0x89, 0x00, 0x45, 0x18, 0xac, 0x42, 0x01, 0xd1, 0x30, 0x00, + 0x70, 0xbd, 0x20, 0x68, 0xff, 0xf7, 0xe4, 0xff, 0x01, 0xc4, 0x43, 0x1e, + 0x98, 0x41, 0x40, 0x42, 0x06, 0x40, 0xf2, 0xe7, 0x05, 0x4b, 0x06, 0x4a, + 0x13, 0x60, 0x06, 0x4a, 0x13, 0x60, 0x53, 0x60, 0x93, 0x60, 0xd3, 0x60, + 0x13, 0x61, 0x53, 0x61, 0x93, 0x61, 0x70, 0x47, 0x80, 0x80, 0x80, 0x80, + 0x00, 0xe4, 0x00, 0xe0, 0x04, 0xe4, 0x00, 0xe0, 0x00, 0x21, 0x04, 0x4b, + 0x04, 0x4a, 0xbf, 0xf3, 0x5f, 0x8f, 0x02, 0xc3, 0x93, 0x42, 0xfa, 0xd1, + 0x70, 0x47, 0xc0, 0x46, 0x00, 0x01, 0x00, 0xd0, 0x80, 0x01, 0x00, 0xd0, + 0x04, 0x4a, 0x10, 0x78, 0x43, 0x1c, 0xdb, 0xb2, 0x17, 0x2b, 0x01, 0xd8, + 0x13, 0x70, 0x70, 0x47, 0x10, 0x23, 0xfb, 0xe7, 0x78, 0x25, 0x00, 0x20, + 0x02, 0x4b, 0xc9, 0x18, 0x89, 0x00, 0x01, 0x60, 0x70, 0x47, 0xc0, 0x46, + 0x40, 0x00, 0x00, 0x34, 0x70, 0x47, 0x10, 0xb5, 0x04, 0x00, 0xff, 0xf7, + 0xe7, 0xff, 0x01, 0x00, 0x20, 0x00, 0xff, 0xf7, 0xef, 0xff, 0xff, 0x23, + 0x23, 0x71, 0xbf, 0xf3, 0x5f, 0x8f, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x00, + 0xff, 0xf7, 0xda, 0xff, 0x01, 0x00, 0x20, 0x00, 0xff, 0xf7, 0xe2, 0xff, + 0xff, 0x23, 0xa3, 0x80, 0xbf, 0xf3, 0x5f, 0x8f, 0x10, 0xbd, 0x00, 0x00, + 0xf8, 0xb5, 0x04, 0x00, 0x0c, 0x20, 0x17, 0x00, 0x1e, 0x00, 0x0d, 0x00, + 0x00, 0xf0, 0x4c, 0xf9, 0x1d, 0x49, 0x41, 0x43, 0x38, 0x00, 0x00, 0xf0, + 0x47, 0xf9, 0x06, 0x9a, 0x33, 0x04, 0x12, 0x03, 0x13, 0x43, 0x22, 0x68, + 0x00, 0x2a, 0x0f, 0xda, 0x3f, 0x21, 0x22, 0x68, 0x0a, 0x40, 0xaa, 0x42, + 0x0a, 0xd1, 0xa2, 0x68, 0x12, 0x05, 0x12, 0x0d, 0x82, 0x42, 0x05, 0xd1, + 0xee, 0x21, 0xe2, 0x68, 0xc9, 0x02, 0x0a, 0x40, 0x9a, 0x42, 0x1b, 0xd0, + 0x10, 0x4a, 0x94, 0x42, 0x19, 0xd0, 0x80, 0x22, 0x52, 0x01, 0x0f, 0x49, + 0x0f, 0x4e, 0x0a, 0x60, 0x0f, 0x49, 0x0a, 0x60, 0x17, 0x00, 0xb1, 0x68, + 0x8f, 0x43, 0xfb, 0xd1, 0xc0, 0x22, 0x21, 0x1d, 0x92, 0x01, 0x0a, 0x43, + 0x21, 0x21, 0x25, 0x60, 0xa0, 0x60, 0x11, 0x60, 0x21, 0x68, 0x00, 0x29, + 0xfc, 0xda, 0xe3, 0x60, 0x08, 0x23, 0x13, 0x60, 0xf8, 0xbd, 0x80, 0x22, + 0x92, 0x01, 0xe4, 0xe7, 0x40, 0x42, 0x0f, 0x00, 0x00, 0xc0, 0x02, 0x40, + 0x00, 0xe0, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xf0, 0x00, 0x40, + 0x80, 0x23, 0x02, 0x4a, 0x9b, 0x00, 0x03, 0x43, 0xd3, 0x62, 0x70, 0x47, + 0x00, 0x80, 0x05, 0x40, 0x02, 0x4b, 0x1a, 0x68, 0x02, 0x4b, 0x5a, 0x60, + 0x70, 0x47, 0xc0, 0x46, 0xbc, 0x2a, 0x00, 0x20, 0x00, 0x80, 0x05, 0x40, + 0x03, 0x00, 0x80, 0x20, 0x12, 0x4a, 0xc0, 0x05, 0x10, 0xb5, 0x12, 0x4c, + 0x10, 0x60, 0x12, 0x48, 0x04, 0x60, 0xe0, 0x20, 0x11, 0x4c, 0xc0, 0x04, + 0x00, 0x29, 0x06, 0xd0, 0x20, 0x60, 0x00, 0x2b, 0x05, 0xd1, 0x80, 0x23, + 0x1b, 0x06, 0x23, 0x60, 0x10, 0xbd, 0x10, 0x60, 0xf7, 0xe7, 0xfa, 0x20, + 0x80, 0x22, 0xc0, 0x00, 0x58, 0x43, 0x52, 0x04, 0x09, 0x4b, 0x90, 0x42, + 0x05, 0xd2, 0x18, 0x60, 0xff, 0xf7, 0xd4, 0xff, 0x80, 0x23, 0xdb, 0x05, + 0xed, 0xe7, 0x06, 0x4a, 0x1a, 0x60, 0xf7, 0xe7, 0x00, 0xb0, 0x05, 0x40, + 0xfc, 0xff, 0x01, 0x00, 0x08, 0x20, 0x01, 0x40, 0x00, 0xa0, 0x05, 0x40, + 0xbc, 0x2a, 0x00, 0x20, 0xff, 0xff, 0xff, 0x00, 0x70, 0xb5, 0x04, 0x00, + 0x10, 0x00, 0x80, 0x22, 0x0a, 0x4b, 0xd2, 0x05, 0x1a, 0x60, 0x0a, 0x4b, + 0x00, 0x2c, 0x0c, 0xd0, 0x01, 0x25, 0x09, 0x4a, 0x2c, 0x43, 0xda, 0x61, + 0x08, 0x4a, 0x62, 0x40, 0x1a, 0x62, 0x59, 0x62, 0x9c, 0x62, 0x00, 0x21, + 0xff, 0xf7, 0xb6, 0xff, 0x70, 0xbd, 0xdc, 0x61, 0xf9, 0xe7, 0xc0, 0x46, + 0x00, 0xb0, 0x05, 0x40, 0x00, 0x80, 0x05, 0x40, 0xd3, 0xc0, 0x07, 0xb0, + 0x2d, 0x3f, 0xf8, 0x4f, 0xaa, 0x22, 0x06, 0x4b, 0x12, 0x01, 0x1a, 0x60, + 0x21, 0x32, 0xff, 0x32, 0xda, 0x60, 0x04, 0x49, 0x04, 0x4a, 0x11, 0x60, + 0x5a, 0x68, 0x00, 0x2a, 0xfc, 0xda, 0x70, 0x47, 0x00, 0x40, 0x02, 0x40, + 0x00, 0xb0, 0xfa, 0x00, 0x00, 0x60, 0x02, 0x40, 0x23, 0x4b, 0x24, 0x4a, + 0x70, 0xb5, 0x1a, 0x60, 0x23, 0x4a, 0x24, 0x4c, 0x15, 0x00, 0x24, 0x4b, + 0x23, 0x60, 0x18, 0x00, 0x91, 0x68, 0x88, 0x43, 0xfb, 0xd1, 0x22, 0x4e, + 0x22, 0x4b, 0x9e, 0x42, 0x24, 0xd3, 0xfe, 0xf7, 0xd1, 0xfb, 0x21, 0x4b, + 0x23, 0x60, 0xab, 0x68, 0xdb, 0x01, 0x80, 0x33, 0xfb, 0xd1, 0x40, 0x22, + 0x1e, 0x4b, 0x1f, 0x48, 0x9a, 0x67, 0x5a, 0x67, 0x1a, 0x67, 0xda, 0x66, + 0x1d, 0x4b, 0x98, 0x42, 0x15, 0xd3, 0x1d, 0x4c, 0x1d, 0x4d, 0xa1, 0x68, + 0xc0, 0x22, 0x28, 0x00, 0x00, 0xf0, 0x1a, 0xf9, 0xa5, 0x60, 0xff, 0xf7, + 0xcb, 0xfe, 0xff, 0xf7, 0xb7, 0xfe, 0xff, 0xf7, 0xe9, 0xfe, 0x18, 0x4c, + 0x18, 0x4b, 0x9c, 0x42, 0x0f, 0xd3, 0x70, 0xbd, 0x08, 0xce, 0x98, 0x47, + 0xd4, 0xe7, 0x04, 0x00, 0x03, 0x68, 0x08, 0x34, 0x00, 0x2b, 0x03, 0xd0, + 0xff, 0xf7, 0xe8, 0xfe, 0x20, 0x00, 0xdd, 0xe7, 0xff, 0xf7, 0xd7, 0xfe, + 0xfa, 0xe7, 0x08, 0xcc, 0x98, 0x47, 0xe9, 0xe7, 0x00, 0xe0, 0x00, 0x40, + 0xbf, 0xcd, 0xfb, 0xfe, 0x00, 0xc0, 0x00, 0x40, 0x00, 0xf0, 0x00, 0x40, + 0xfe, 0x7f, 0x3c, 0x00, 0xa8, 0x25, 0x00, 0x20, 0xb8, 0x25, 0x00, 0x20, + 0xff, 0xff, 0xff, 0x01, 0x00, 0xf0, 0x01, 0x40, 0xa0, 0x25, 0x00, 0x20, + 0xa8, 0x25, 0x00, 0x20, 0x00, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x20, + 0xb8, 0x25, 0x00, 0x20, 0xbc, 0x25, 0x00, 0x20, 0x00, 0xb5, 0x00, 0xbe, + 0xfe, 0xe7, 0x00, 0x00, 0x10, 0xb5, 0x01, 0x48, 0xff, 0xf7, 0xf8, 0xff, + 0x60, 0x25, 0x00, 0x20, 0x01, 0x48, 0x04, 0x21, 0x01, 0x4b, 0x18, 0x47, + 0x80, 0x25, 0x00, 0x20, 0x2d, 0x1c, 0x00, 0x20, 0x01, 0x4b, 0x5b, 0x68, + 0x18, 0x47, 0x00, 0x00, 0x80, 0x25, 0x00, 0x20, 0x01, 0x4b, 0x9b, 0x68, + 0x18, 0x47, 0x00, 0x00, 0x80, 0x25, 0x00, 0x20, 0x01, 0x4b, 0x1b, 0x68, + 0x18, 0x47, 0x00, 0x00, 0x80, 0x25, 0x00, 0x20, 0x11, 0x4a, 0x93, 0x6f, + 0x9b, 0x08, 0x13, 0xd2, 0x10, 0x66, 0x51, 0x66, 0x00, 0x29, 0x05, 0xd0, + 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, 0x51, 0x6f, 0x10, 0x6f, 0x70, 0x47, + 0x04, 0xb5, 0x00, 0x28, 0x01, 0xd0, 0x00, 0x20, 0xc0, 0x43, 0x00, 0xf0, + 0xab, 0xf8, 0x00, 0x21, 0x04, 0xbd, 0xc0, 0x46, 0xf0, 0xb5, 0x14, 0x6e, + 0x55, 0x6e, 0x57, 0x6f, 0x16, 0x6f, 0xff, 0xf7, 0xe5, 0xff, 0x14, 0x66, + 0x55, 0x66, 0x57, 0x67, 0x16, 0x67, 0xf0, 0xbd, 0x00, 0x00, 0x00, 0xd0, + 0x13, 0x23, 0x70, 0xb5, 0x1c, 0x78, 0x0f, 0x4d, 0x01, 0x2c, 0x0e, 0xd1, + 0x00, 0x23, 0x0e, 0x49, 0x9a, 0x00, 0x01, 0x33, 0xa9, 0x50, 0x20, 0x2b, + 0xfa, 0xd1, 0x0b, 0x4b, 0xab, 0x64, 0x0b, 0x48, 0xff, 0xf7, 0x02, 0xfe, + 0x0a, 0x4b, 0x18, 0x60, 0x70, 0xbd, 0x01, 0x2c, 0xf5, 0xdd, 0x09, 0x48, + 0xff, 0xf7, 0x02, 0xfe, 0x80, 0x22, 0x01, 0x00, 0x28, 0x00, 0x00, 0xf0, + 0x75, 0xf8, 0x02, 0x2c, 0xed, 0xd1, 0xea, 0xe7, 0xcc, 0xd3, 0x00, 0x20, + 0x3d, 0x20, 0x00, 0x20, 0x4c, 0x33, 0x00, 0x00, 0xc4, 0x2f, 0x00, 0x20, + 0x53, 0x44, 0x00, 0x00, 0x07, 0xb5, 0x60, 0x46, 0x01, 0x88, 0x0a, 0x0a, + 0x02, 0x30, 0xdf, 0x2a, 0xfa, 0xd1, 0xc9, 0xb2, 0x82, 0x08, 0x04, 0xd3, + 0x02, 0x88, 0x40, 0x88, 0x00, 0x04, 0x10, 0x43, 0x00, 0xe0, 0x00, 0x68, + 0x01, 0x4a, 0x50, 0x50, 0x03, 0x90, 0x07, 0xbd, 0xcc, 0xd3, 0x00, 0x20, + 0x13, 0x23, 0x10, 0xb5, 0x10, 0x48, 0x1c, 0x78, 0xff, 0xf7, 0xd4, 0xfd, + 0x01, 0x00, 0x01, 0x2c, 0x13, 0xd1, 0x0e, 0x4c, 0x54, 0x22, 0x20, 0x00, + 0x00, 0xf0, 0x44, 0xf8, 0x15, 0x23, 0x0c, 0x4a, 0x99, 0x00, 0x01, 0x33, + 0x62, 0x50, 0x20, 0x2b, 0xfa, 0xd1, 0x22, 0x62, 0xe2, 0x61, 0x09, 0x48, + 0xff, 0xf7, 0xb8, 0xfd, 0x08, 0x4b, 0x18, 0x60, 0x10, 0xbd, 0x01, 0x2c, + 0xf7, 0xdd, 0x80, 0x22, 0x02, 0x48, 0x00, 0xf0, 0x2f, 0xf8, 0xf2, 0xe7, + 0x53, 0x46, 0x00, 0x00, 0xcc, 0xd4, 0x00, 0x20, 0xc5, 0x20, 0x00, 0x20, + 0x4c, 0x33, 0x00, 0x00, 0xc4, 0x2f, 0x00, 0x20, 0x07, 0xb5, 0x60, 0x46, + 0x01, 0x88, 0x0a, 0x0a, 0x02, 0x30, 0xdf, 0x2a, 0xfa, 0xd1, 0xc9, 0xb2, + 0x82, 0x08, 0x04, 0xd3, 0x02, 0x88, 0x40, 0x88, 0x00, 0x04, 0x10, 0x43, + 0x00, 0xe0, 0x00, 0x68, 0x01, 0x4a, 0x50, 0x50, 0x03, 0x90, 0x07, 0xbd, + 0xcc, 0xd4, 0x00, 0x20, 0x01, 0x48, 0x04, 0x21, 0x01, 0x4b, 0x18, 0x47, + 0x90, 0x25, 0x00, 0x20, 0x2d, 0x1c, 0x00, 0x20, 0x01, 0x4b, 0x1b, 0x68, + 0x18, 0x47, 0x00, 0x00, 0x90, 0x25, 0x00, 0x20, 0x01, 0x4b, 0x5b, 0x68, + 0x18, 0x47, 0x00, 0x00, 0x90, 0x25, 0x00, 0x20, 0x70, 0x47, 0xc0, 0x46, + 0x30, 0xb5, 0x03, 0x2a, 0x0c, 0xd9, 0x03, 0x00, 0x0b, 0x43, 0x9b, 0x07, + 0x1c, 0xd1, 0x03, 0x68, 0x0c, 0x68, 0xa3, 0x42, 0x18, 0xd1, 0x04, 0x3a, + 0x04, 0x30, 0x04, 0x31, 0x03, 0x2a, 0xf6, 0xd8, 0x55, 0x1e, 0x00, 0x2a, + 0x0e, 0xd0, 0x02, 0x78, 0x0c, 0x78, 0x94, 0x42, 0x0e, 0xd1, 0x01, 0x35, + 0x01, 0x23, 0x01, 0x39, 0x04, 0xe0, 0xc2, 0x5c, 0x01, 0x33, 0xcc, 0x5c, + 0xa2, 0x42, 0x05, 0xd1, 0xab, 0x42, 0xf8, 0xd1, 0x00, 0x20, 0x30, 0xbd, + 0x55, 0x1e, 0xec, 0xe7, 0x10, 0x1b, 0xfa, 0xe7, 0x03, 0x23, 0xca, 0xb2, + 0xf0, 0xb5, 0x03, 0x40, 0x00, 0x2a, 0x39, 0xd0, 0x00, 0x2b, 0x0e, 0xd0, + 0x03, 0x78, 0x00, 0x2b, 0x57, 0xd0, 0x9a, 0x42, 0x31, 0xd0, 0x03, 0x24, + 0x04, 0xe0, 0x03, 0x78, 0x00, 0x2b, 0x50, 0xd0, 0x93, 0x42, 0x2a, 0xd0, + 0x01, 0x30, 0x20, 0x42, 0xf7, 0xd1, 0xff, 0x25, 0x29, 0x40, 0x0d, 0x02, + 0x29, 0x43, 0x0d, 0x04, 0x0d, 0x43, 0x2c, 0x00, 0x01, 0x68, 0x23, 0x4e, + 0x4c, 0x40, 0x8b, 0x19, 0x8b, 0x43, 0xa1, 0x19, 0xa1, 0x43, 0x21, 0x4e, + 0x0b, 0x43, 0x33, 0x42, 0x0b, 0xd1, 0x04, 0x30, 0x01, 0x68, 0x1d, 0x4f, + 0x0c, 0x00, 0xcb, 0x19, 0x6c, 0x40, 0x8b, 0x43, 0xe1, 0x19, 0xa1, 0x43, + 0x0b, 0x43, 0x33, 0x42, 0xf3, 0xd0, 0x03, 0x78, 0x00, 0x2b, 0x04, 0xd1, + 0x29, 0xe0, 0x01, 0x30, 0x03, 0x78, 0x00, 0x2b, 0x25, 0xd0, 0x9a, 0x42, + 0xf9, 0xd1, 0xf0, 0xbd, 0x00, 0x2b, 0x0a, 0xd0, 0x03, 0x78, 0x00, 0x2b, + 0xf9, 0xd0, 0x03, 0x22, 0x02, 0xe0, 0x03, 0x78, 0x00, 0x2b, 0xf4, 0xd0, + 0x01, 0x30, 0x10, 0x42, 0xf9, 0xd1, 0x02, 0x68, 0x0b, 0x4b, 0x0c, 0x49, + 0xd3, 0x18, 0x93, 0x43, 0x0b, 0x42, 0x06, 0xd1, 0x04, 0x30, 0x02, 0x68, + 0x07, 0x4b, 0xd3, 0x18, 0x93, 0x43, 0x0b, 0x42, 0xf8, 0xd0, 0x03, 0x78, + 0x00, 0x2b, 0xe0, 0xd0, 0x01, 0x30, 0x03, 0x78, 0x00, 0x2b, 0xfb, 0xd1, + 0xdb, 0xe7, 0x00, 0x20, 0xd9, 0xe7, 0xc0, 0x46, 0xff, 0xfe, 0xfe, 0xfe, + 0x80, 0x80, 0x80, 0x80, 0x70, 0xb5, 0x04, 0x78, 0x00, 0x2c, 0x13, 0xd0, + 0x05, 0x00, 0x0e, 0x78, 0x00, 0x2e, 0x09, 0xd0, 0xa6, 0x42, 0x0b, 0xd0, + 0x0b, 0x00, 0x01, 0xe0, 0xa2, 0x42, 0x07, 0xd0, 0x01, 0x33, 0x1a, 0x78, + 0x00, 0x2a, 0xf9, 0xd1, 0x01, 0x35, 0x2c, 0x78, 0x00, 0x2c, 0xef, 0xd1, + 0x28, 0x1a, 0x70, 0xbd, 0x00, 0x20, 0xfc, 0xe7, 0x70, 0xb5, 0x04, 0x78, + 0x00, 0x2c, 0x14, 0xd0, 0x05, 0x00, 0x0e, 0x78, 0x00, 0x2e, 0x09, 0xd0, + 0xa6, 0x42, 0x09, 0xd0, 0x0b, 0x00, 0x01, 0xe0, 0xa2, 0x42, 0x05, 0xd0, + 0x01, 0x33, 0x1a, 0x78, 0x00, 0x2a, 0xf9, 0xd1, 0x28, 0x1a, 0x70, 0xbd, + 0x01, 0x35, 0x2c, 0x78, 0x00, 0x2c, 0xed, 0xd1, 0xf8, 0xe7, 0x00, 0x20, + 0xf7, 0xe7, 0xc0, 0x46, 0xf8, 0xb5, 0xc0, 0x46, 0x08, 0x4a, 0x10, 0xb5, + 0x13, 0x78, 0x00, 0x2b, 0x0a, 0xd1, 0x80, 0x23, 0x06, 0x48, 0x07, 0x49, + 0x5b, 0x05, 0x1c, 0x68, 0xc4, 0x50, 0x04, 0x33, 0x8b, 0x42, 0xfa, 0xd1, + 0x01, 0x23, 0x13, 0x70, 0x10, 0xbd, 0xc0, 0x46, 0xc9, 0x50, 0x00, 0x20, + 0x94, 0x29, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, 0x10, 0xb5, 0x02, 0x4b, + 0x01, 0x33, 0x98, 0x47, 0x10, 0xbd, 0xc0, 0x46, 0x94, 0x29, 0x00, 0x20, + 0x80, 0x23, 0xf0, 0xb5, 0x42, 0x18, 0x04, 0x00, 0x0d, 0x00, 0x85, 0xb0, + 0x5b, 0x04, 0x9a, 0x42, 0x01, 0xd9, 0xff, 0xf7, 0x29, 0xfe, 0x14, 0x27, + 0x18, 0x26, 0x38, 0x88, 0x33, 0x88, 0x12, 0x49, 0x98, 0x47, 0x33, 0x88, + 0x03, 0x90, 0x11, 0x49, 0x38, 0x88, 0x98, 0x47, 0x33, 0x88, 0x02, 0x90, + 0x0f, 0x49, 0x38, 0x88, 0x98, 0x47, 0x33, 0x88, 0x0e, 0x49, 0x01, 0x90, + 0x38, 0x88, 0x98, 0x47, 0x06, 0x00, 0xff, 0xf7, 0xbd, 0xff, 0x03, 0x9b, + 0x98, 0x47, 0x02, 0x9b, 0x98, 0x47, 0x80, 0x22, 0x20, 0x00, 0xd8, 0x23, + 0x29, 0x00, 0x52, 0x02, 0x01, 0x9c, 0xa0, 0x47, 0xb0, 0x47, 0xff, 0xf7, + 0xc7, 0xff, 0x05, 0xb0, 0xf0, 0xbd, 0xc0, 0x46, 0x49, 0x46, 0x00, 0x00, + 0x45, 0x58, 0x00, 0x00, 0x52, 0x45, 0x00, 0x00, 0x46, 0x43, 0x00, 0x00, + 0x80, 0x23, 0xf0, 0xb5, 0x17, 0x00, 0x85, 0xb0, 0x82, 0x18, 0x04, 0x00, + 0x03, 0x91, 0x5b, 0x04, 0x9a, 0x42, 0x01, 0xd9, 0xff, 0xf7, 0xec, 0xfd, + 0x14, 0x26, 0x18, 0x25, 0x30, 0x88, 0x2b, 0x88, 0x10, 0x49, 0x98, 0x47, + 0x2b, 0x88, 0x02, 0x90, 0x0f, 0x49, 0x30, 0x88, 0x98, 0x47, 0x2b, 0x88, + 0x01, 0x90, 0x0e, 0x49, 0x30, 0x88, 0x98, 0x47, 0x2b, 0x88, 0x0d, 0x49, + 0x00, 0x90, 0x30, 0x88, 0x98, 0x47, 0x05, 0x00, 0xff, 0xf7, 0x80, 0xff, + 0x02, 0x9b, 0x98, 0x47, 0x01, 0x9b, 0x98, 0x47, 0x3a, 0x00, 0x20, 0x00, + 0x03, 0x99, 0x00, 0x9b, 0x98, 0x47, 0xa8, 0x47, 0xff, 0xf7, 0x8c, 0xff, + 0x05, 0xb0, 0xf0, 0xbd, 0x49, 0x46, 0x00, 0x00, 0x45, 0x58, 0x00, 0x00, + 0x52, 0x50, 0x00, 0x00, 0x46, 0x43, 0x00, 0x00, 0x50, 0x69, 0x63, 0x6f, + 0x20, 0x4f, 0x54, 0x41, 0x00, 0x2f, 0x00, 0x2e, 0x2e, 0x00, 0x6c, 0x69, + 0x74, 0x74, 0x6c, 0x65, 0x66, 0x73, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x64, 0x10, 0xb7, 0x1d, + 0xc8, 0x20, 0x6e, 0x3b, 0xac, 0x30, 0xd9, 0x26, 0x90, 0x41, 0xdc, 0x76, + 0xf4, 0x51, 0x6b, 0x6b, 0x58, 0x61, 0xb2, 0x4d, 0x3c, 0x71, 0x05, 0x50, + 0x20, 0x83, 0xb8, 0xed, 0x44, 0x93, 0x0f, 0xf0, 0xe8, 0xa3, 0xd6, 0xd6, + 0x8c, 0xb3, 0x61, 0xcb, 0xb0, 0xc2, 0x64, 0x9b, 0xd4, 0xd2, 0xd3, 0x86, + 0x78, 0xe2, 0x0a, 0xa0, 0x1c, 0xf2, 0xbd, 0xbd, 0x10, 0x11, 0x12, 0x00, + 0x08, 0x07, 0x09, 0x06, 0x0a, 0x05, 0x0b, 0x04, 0x0c, 0x03, 0x0d, 0x02, + 0x0e, 0x01, 0x0f, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, + 0x05, 0x00, 0x07, 0x00, 0x09, 0x00, 0x0d, 0x00, 0x11, 0x00, 0x19, 0x00, + 0x21, 0x00, 0x31, 0x00, 0x41, 0x00, 0x61, 0x00, 0x81, 0x00, 0xc1, 0x00, + 0x01, 0x01, 0x81, 0x01, 0x01, 0x02, 0x01, 0x03, 0x01, 0x04, 0x01, 0x06, + 0x01, 0x08, 0x01, 0x0c, 0x01, 0x10, 0x01, 0x18, 0x01, 0x20, 0x01, 0x30, + 0x01, 0x40, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, + 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, + 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0c, 0x0c, 0x0d, 0x0d, 0x03, 0x00, + 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08, 0x00, 0x09, 0x00, + 0x0a, 0x00, 0x0b, 0x00, 0x0d, 0x00, 0x0f, 0x00, 0x11, 0x00, 0x13, 0x00, + 0x17, 0x00, 0x1b, 0x00, 0x1f, 0x00, 0x23, 0x00, 0x2b, 0x00, 0x33, 0x00, + 0x3b, 0x00, 0x43, 0x00, 0x53, 0x00, 0x63, 0x00, 0x73, 0x00, 0x83, 0x00, + 0xa3, 0x00, 0xc3, 0x00, 0xe3, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, + 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, + 0x05, 0x05, 0x00, 0x00, 0x52, 0x65, 0x6c, 0x57, 0x69, 0x74, 0x68, 0x44, + 0x65, 0x62, 0x49, 0x6e, 0x66, 0x6f, 0x00, 0x62, 0x6f, 0x6f, 0x74, 0x32, + 0x5f, 0x77, 0x32, 0x35, 0x71, 0x30, 0x38, 0x30, 0x00, 0x31, 0x2e, 0x34, + 0x2e, 0x30, 0x00, 0x70, 0x69, 0x63, 0x6f, 0x00, 0x6f, 0x74, 0x61, 0x00, + 0x41, 0x75, 0x67, 0x20, 0x31, 0x30, 0x20, 0x32, 0x30, 0x32, 0x32, 0x00, + 0x06, 0x00, 0x52, 0x50, 0xbb, 0xff, 0x3c, 0xb6, 0x27, 0x25, 0x00, 0x20, + 0x06, 0x00, 0x52, 0x50, 0xe1, 0x82, 0x88, 0x7f, 0x13, 0x25, 0x00, 0x20, + 0x06, 0x00, 0x52, 0x50, 0xd3, 0xf0, 0x75, 0x42, 0x04, 0x25, 0x00, 0x20, + 0x48, 0x61, 0x72, 0x64, 0x20, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x00, + 0xc8, 0x3f, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0x00, 0x00, + 0x4c, 0x33, 0x00, 0x00, 0x54, 0x33, 0x00, 0x00, 0x52, 0x33, 0x00, 0x00, + 0x4d, 0x53, 0x00, 0x00, 0x4d, 0x43, 0x00, 0x00, 0x53, 0x34, 0x00, 0x00, + 0x43, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf1, 0x20, 0x00, 0x20, 0x65, 0x1f, 0x00, 0x20, 0xe5, 0x1f, 0x00, 0x20, + 0x69, 0x20, 0x00, 0x20, 0x39, 0x01, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xde, 0xc0, 0x0e, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x04, 0x20, 0xf7, 0x40, 0x00, 0x10, + 0xc3, 0x40, 0x00, 0x10, 0xc5, 0x40, 0x00, 0x10, 0xc1, 0x40, 0x00, 0x10, + 0xc1, 0x40, 0x00, 0x10, 0xc1, 0x40, 0x00, 0x10, 0xc1, 0x40, 0x00, 0x10, + 0xc1, 0x40, 0x00, 0x10, 0xc1, 0x40, 0x00, 0x10, 0xc1, 0x40, 0x00, 0x10, + 0xc7, 0x40, 0x00, 0x10, 0xc1, 0x40, 0x00, 0x10, 0xc1, 0x40, 0x00, 0x10, + 0xc9, 0x40, 0x00, 0x10, 0xcb, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, 0xcd, 0x40, 0x00, 0x10, + 0xcd, 0x40, 0x00, 0x10, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xbe, + 0x00, 0xbe, 0x00, 0xbe, 0x00, 0xf0, 0x4b, 0xf8, 0x10, 0x38, 0x00, 0xbe, + 0xf2, 0xeb, 0x88, 0x71, 0x4c, 0x05, 0x01, 0x10, 0x4c, 0x05, 0x01, 0x10, + 0x34, 0x41, 0x00, 0x10, 0x90, 0xa3, 0x1a, 0xe7, 0x00, 0x20, 0x21, 0x49, + 0x08, 0x60, 0x06, 0xc8, 0x81, 0xf3, 0x08, 0x88, 0x10, 0x47, 0x1f, 0x48, + 0x00, 0x68, 0x00, 0x28, 0x2f, 0xd1, 0x0d, 0xa4, 0x0e, 0xcc, 0x00, 0x29, + 0x02, 0xd0, 0x00, 0xf0, 0x12, 0xf8, 0xf9, 0xe7, 0x1a, 0x49, 0x1b, 0x4a, + 0x00, 0x20, 0x00, 0xe0, 0x01, 0xc1, 0x91, 0x42, 0xfc, 0xd1, 0x19, 0x49, + 0x88, 0x47, 0x19, 0x49, 0x88, 0x47, 0x19, 0x49, 0x88, 0x47, 0x00, 0xbe, + 0xfd, 0xe7, 0x01, 0xc9, 0x01, 0xc2, 0x9a, 0x42, 0xfb, 0xd3, 0x70, 0x47, + 0x4c, 0x05, 0x01, 0x10, 0xc0, 0x00, 0x00, 0x20, 0x84, 0x0c, 0x00, 0x20, + 0x10, 0x11, 0x01, 0x10, 0x00, 0x00, 0x04, 0x20, 0x00, 0x00, 0x04, 0x20, + 0x10, 0x11, 0x01, 0x10, 0x00, 0x10, 0x04, 0x20, 0x00, 0x10, 0x04, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x70, 0x47, 0x0b, 0x48, 0x02, 0xf0, 0x22, 0xf8, + 0x00, 0x47, 0xef, 0xf3, 0x05, 0x80, 0xc0, 0xb2, 0x70, 0x47, 0x00, 0x00, + 0x08, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0xd0, 0x88, 0x0c, 0x00, 0x20, + 0x34, 0x1c, 0x00, 0x20, 0x45, 0x65, 0x00, 0x10, 0xb1, 0x48, 0x00, 0x10, + 0x45, 0x66, 0x00, 0x10, 0x57, 0x56, 0x00, 0x00, 0xf8, 0xb5, 0xc0, 0x46, + 0x04, 0x48, 0x05, 0x4b, 0x10, 0xb5, 0x83, 0x42, 0x03, 0xd0, 0x04, 0x4b, + 0x00, 0x2b, 0x00, 0xd0, 0x98, 0x47, 0x10, 0xbd, 0x84, 0x0c, 0x00, 0x20, + 0x84, 0x0c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x06, 0x48, 0x07, 0x49, + 0x09, 0x1a, 0x8b, 0x10, 0xc9, 0x0f, 0xc9, 0x18, 0x10, 0xb5, 0x49, 0x10, + 0x03, 0xd0, 0x04, 0x4b, 0x00, 0x2b, 0x00, 0xd0, 0x98, 0x47, 0x10, 0xbd, + 0x84, 0x0c, 0x00, 0x20, 0x84, 0x0c, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xb5, 0x07, 0x4c, 0x23, 0x78, 0x00, 0x2b, 0x09, 0xd1, 0xff, 0xf7, + 0xd5, 0xff, 0x05, 0x4b, 0x00, 0x2b, 0x02, 0xd0, 0x04, 0x48, 0x00, 0xe0, + 0x00, 0xbf, 0x01, 0x23, 0x23, 0x70, 0x10, 0xbd, 0xd0, 0x0d, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xf8, 0xfc, 0x00, 0x10, 0x05, 0x4b, 0x10, 0xb5, + 0x00, 0x2b, 0x03, 0xd0, 0x04, 0x49, 0x05, 0x48, 0x00, 0xe0, 0x00, 0xbf, + 0xff, 0xf7, 0xcc, 0xff, 0x10, 0xbd, 0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, + 0xd4, 0x0d, 0x00, 0x20, 0xf8, 0xfc, 0x00, 0x10, 0x70, 0xb5, 0xfa, 0x25, + 0x0a, 0x4c, 0x0b, 0x4e, 0x22, 0x68, 0x6d, 0x00, 0x30, 0x00, 0x0a, 0x49, + 0x00, 0xf0, 0xd0, 0xf9, 0x28, 0x00, 0x00, 0xf0, 0xfc, 0xf9, 0x22, 0x68, + 0x30, 0x00, 0x53, 0x1c, 0x06, 0x49, 0x23, 0x60, 0x00, 0xf0, 0xc6, 0xf9, + 0x28, 0x00, 0x00, 0xf0, 0xf2, 0xf9, 0x70, 0xbd, 0x34, 0x14, 0x00, 0x20, + 0x24, 0x0e, 0x00, 0x20, 0xf8, 0xfc, 0x00, 0x10, 0x05, 0xfd, 0x00, 0x10, + 0xe1, 0x21, 0x10, 0xb5, 0x02, 0x48, 0x49, 0x02, 0x00, 0xf0, 0x09, 0xf8, + 0x10, 0xbd, 0xc0, 0x46, 0x24, 0x0e, 0x00, 0x20, 0x10, 0xb5, 0x03, 0x68, + 0xdb, 0x69, 0x98, 0x47, 0x10, 0xbd, 0x03, 0x7c, 0x00, 0x2b, 0x01, 0xd1, + 0x01, 0x33, 0x03, 0x74, 0x70, 0x47, 0x70, 0x47, 0x13, 0xb5, 0x6b, 0x46, + 0x02, 0x68, 0xd9, 0x71, 0x07, 0x33, 0x54, 0x68, 0x19, 0x00, 0x01, 0x22, + 0xa0, 0x47, 0x16, 0xbd, 0x96, 0x23, 0x09, 0x4a, 0x10, 0xb5, 0x12, 0x68, + 0xdb, 0x00, 0x9a, 0x42, 0x0a, 0xd1, 0x07, 0x4b, 0x1c, 0x78, 0x00, 0x2c, + 0x06, 0xd1, 0x06, 0x48, 0x01, 0xf0, 0x70, 0xff, 0x21, 0x00, 0x03, 0x00, + 0x20, 0x00, 0x98, 0x47, 0x10, 0xbd, 0xc0, 0x46, 0xc0, 0x04, 0x00, 0x20, + 0xbc, 0x1a, 0x00, 0x20, 0x55, 0x42, 0x00, 0x00, 0x13, 0xb5, 0x00, 0x23, + 0x04, 0x00, 0x08, 0x00, 0x21, 0x60, 0x23, 0x71, 0x01, 0xa9, 0x0b, 0xf0, + 0xcb, 0xfc, 0x00, 0x28, 0x08, 0xd1, 0xd0, 0x23, 0x1b, 0x06, 0x1b, 0x68, + 0x01, 0x9a, 0x9a, 0x42, 0x04, 0xd0, 0x20, 0x68, 0x0b, 0xf0, 0xe8, 0xfc, + 0x01, 0x23, 0x23, 0x71, 0x20, 0x00, 0x16, 0xbd, 0x10, 0xb5, 0x03, 0x79, + 0x04, 0x00, 0x00, 0x2b, 0x02, 0xd0, 0x00, 0x68, 0x0b, 0xf0, 0x84, 0xfc, + 0x20, 0x00, 0x10, 0xbd, 0x7f, 0xb5, 0x04, 0x00, 0x02, 0xad, 0x28, 0x00, + 0x0d, 0x49, 0xff, 0xf7, 0xd7, 0xff, 0x23, 0x7c, 0x1c, 0x1e, 0x0c, 0xd0, + 0x00, 0x24, 0x2b, 0x79, 0xa3, 0x42, 0x08, 0xd0, 0x6b, 0x46, 0xde, 0x1d, + 0x31, 0x00, 0x20, 0x00, 0x03, 0xf0, 0xb4, 0xff, 0xa0, 0x42, 0x06, 0xd0, + 0x34, 0x78, 0x28, 0x00, 0xff, 0xf7, 0xdc, 0xff, 0x20, 0x00, 0x04, 0xb0, + 0x70, 0xbd, 0x01, 0x24, 0x64, 0x42, 0xf6, 0xe7, 0xb4, 0x0e, 0x00, 0x20, + 0x30, 0xb5, 0x04, 0x00, 0x85, 0xb0, 0x02, 0xad, 0x28, 0x00, 0x13, 0x49, + 0xff, 0xf7, 0xb4, 0xff, 0x23, 0x7c, 0x00, 0x2b, 0x02, 0xd1, 0x01, 0x24, + 0x64, 0x42, 0x16, 0xe0, 0x2b, 0x79, 0x00, 0x2b, 0xf9, 0xd0, 0x00, 0x20, + 0x03, 0xf0, 0x5a, 0xff, 0x00, 0x28, 0xf4, 0xd0, 0x00, 0x20, 0x03, 0xf0, + 0x6d, 0xff, 0x00, 0x28, 0xef, 0xd0, 0x6b, 0x46, 0xdc, 0x1d, 0x01, 0x22, + 0x21, 0x00, 0x00, 0x20, 0x03, 0xf0, 0x70, 0xff, 0x00, 0x28, 0xe6, 0xd0, + 0x24, 0x78, 0x28, 0x00, 0xff, 0xf7, 0xac, 0xff, 0x20, 0x00, 0x05, 0xb0, + 0x30, 0xbd, 0xc0, 0x46, 0xb4, 0x0e, 0x00, 0x20, 0x13, 0xb5, 0x04, 0x00, + 0x0a, 0x49, 0x68, 0x46, 0xff, 0xf7, 0x88, 0xff, 0x23, 0x7c, 0x1c, 0x1e, + 0x08, 0xd0, 0x6b, 0x46, 0x00, 0x24, 0x1b, 0x79, 0xa3, 0x42, 0x03, 0xd0, + 0x20, 0x00, 0x03, 0xf0, 0x47, 0xff, 0x04, 0x00, 0x68, 0x46, 0xff, 0xf7, + 0x91, 0xff, 0x20, 0x00, 0x16, 0xbd, 0xc0, 0x46, 0xb4, 0x0e, 0x00, 0x20, + 0x13, 0xb5, 0x04, 0x00, 0x0a, 0x49, 0x68, 0x46, 0xff, 0xf7, 0x6e, 0xff, + 0x23, 0x7c, 0x1c, 0x1e, 0x08, 0xd0, 0x6b, 0x46, 0x00, 0x24, 0x1b, 0x79, + 0xa3, 0x42, 0x03, 0xd0, 0x20, 0x00, 0x03, 0xf0, 0xaf, 0xff, 0x04, 0x00, + 0x68, 0x46, 0xff, 0xf7, 0x77, 0xff, 0x20, 0x00, 0x16, 0xbd, 0xc0, 0x46, + 0xb4, 0x0e, 0x00, 0x20, 0x13, 0xb5, 0x04, 0x00, 0x09, 0x49, 0x68, 0x46, + 0xff, 0xf7, 0x54, 0xff, 0x23, 0x7c, 0x00, 0x2b, 0x03, 0xd0, 0x6b, 0x46, + 0x1b, 0x79, 0x00, 0x2b, 0x03, 0xd1, 0x68, 0x46, 0xff, 0xf7, 0x62, 0xff, + 0x13, 0xbd, 0x00, 0x20, 0x03, 0xf0, 0x3c, 0xff, 0xf7, 0xe7, 0xc0, 0x46, + 0xb4, 0x0e, 0x00, 0x20, 0xf0, 0xb5, 0x04, 0x00, 0x87, 0xb0, 0x03, 0x91, + 0x04, 0xa8, 0x30, 0x49, 0x02, 0x92, 0xff, 0xf7, 0x39, 0xff, 0x23, 0x7c, + 0x1e, 0x1e, 0x4c, 0xd0, 0x00, 0x26, 0x04, 0xab, 0x1b, 0x79, 0xb3, 0x42, + 0x47, 0xd0, 0x30, 0x00, 0x03, 0xf0, 0xe0, 0xfe, 0x04, 0x00, 0xb0, 0x42, + 0x47, 0xd0, 0x01, 0x96, 0x02, 0x9b, 0x9e, 0x42, 0x3c, 0xd2, 0x00, 0x20, + 0x9f, 0x1b, 0x03, 0xf0, 0x6f, 0xff, 0x05, 0x00, 0xb8, 0x42, 0x00, 0xdd, + 0x3d, 0x00, 0x00, 0x2d, 0x15, 0xd0, 0x03, 0x9b, 0x2a, 0x00, 0x99, 0x19, + 0x00, 0x20, 0x03, 0xf0, 0x49, 0xff, 0x05, 0x00, 0x03, 0xf0, 0x16, 0xfb, + 0x00, 0x20, 0x03, 0xf0, 0x07, 0xff, 0x01, 0x9b, 0x76, 0x19, 0x5b, 0x19, + 0x01, 0x93, 0x01, 0xf0, 0x61, 0xfc, 0x18, 0x4b, 0x18, 0x60, 0x59, 0x60, + 0xdc, 0xe7, 0x03, 0xf0, 0x07, 0xfb, 0x28, 0x00, 0x03, 0xf0, 0xf8, 0xfe, + 0x28, 0x00, 0x03, 0xf0, 0xb1, 0xfe, 0x00, 0x28, 0x12, 0xd0, 0x28, 0x00, + 0x03, 0xf0, 0x46, 0xff, 0x00, 0x28, 0xcd, 0xd1, 0x00, 0x25, 0x01, 0xf0, + 0x4b, 0xfc, 0x0e, 0x4c, 0x0c, 0x4b, 0x1a, 0x68, 0x5b, 0x68, 0x12, 0x19, + 0x6b, 0x41, 0x99, 0x42, 0x02, 0xd8, 0xc1, 0xd1, 0x90, 0x42, 0xbf, 0xd9, + 0x01, 0x9e, 0x04, 0xa8, 0xff, 0xf7, 0xfe, 0xfe, 0x30, 0x00, 0x07, 0xb0, + 0xf0, 0xbd, 0x00, 0x20, 0x00, 0x21, 0x03, 0x4b, 0x01, 0x94, 0x18, 0x60, + 0x59, 0x60, 0xf1, 0xe7, 0xb4, 0x0e, 0x00, 0x20, 0x88, 0x0c, 0x00, 0x20, + 0x40, 0x42, 0x0f, 0x00, 0x13, 0xb5, 0x04, 0x00, 0x0a, 0x49, 0x68, 0x46, + 0xff, 0xf7, 0xd0, 0xfe, 0x24, 0x7c, 0x00, 0x2c, 0x09, 0xd0, 0x6b, 0x46, + 0x1c, 0x79, 0x00, 0x2c, 0x05, 0xd0, 0x03, 0xf0, 0xc9, 0xfa, 0x00, 0x20, + 0x03, 0xf0, 0x76, 0xfe, 0x04, 0x00, 0x68, 0x46, 0xff, 0xf7, 0xd8, 0xfe, + 0x20, 0x00, 0x16, 0xbd, 0xb4, 0x0e, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, + 0x10, 0xb5, 0x02, 0x4b, 0x19, 0x70, 0xff, 0xf7, 0x9b, 0xfe, 0x10, 0xbd, + 0xbc, 0x1a, 0x00, 0x20, 0x48, 0x78, 0x0b, 0x78, 0x10, 0xb5, 0x8a, 0x78, + 0x00, 0x02, 0x18, 0x43, 0xcb, 0x78, 0x12, 0x04, 0x10, 0x43, 0x1b, 0x06, + 0x02, 0x4a, 0x03, 0x43, 0x13, 0x60, 0xff, 0xf7, 0x89, 0xfe, 0x10, 0xbd, + 0xc0, 0x04, 0x00, 0x20, 0x05, 0x4b, 0x10, 0xb5, 0x00, 0x2b, 0x06, 0xd0, + 0x04, 0x48, 0xff, 0xf7, 0x0b, 0xff, 0x00, 0x28, 0x01, 0xd0, 0x00, 0xe0, + 0x00, 0xbf, 0x10, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x24, 0x0e, 0x00, 0x20, + 0xfa, 0x22, 0x00, 0x21, 0x04, 0x4b, 0x92, 0x00, 0x9a, 0x60, 0x04, 0x4a, + 0x59, 0x60, 0x08, 0x32, 0x1a, 0x60, 0x19, 0x74, 0x70, 0x47, 0xc0, 0x46, + 0x24, 0x0e, 0x00, 0x20, 0x14, 0xfd, 0x00, 0x10, 0x0e, 0xb4, 0xf0, 0xb5, + 0x94, 0xb0, 0x19, 0xad, 0x08, 0xcd, 0x07, 0x00, 0x01, 0x93, 0x40, 0x21, + 0x2b, 0x00, 0x01, 0x9a, 0x04, 0xa8, 0x03, 0x95, 0x07, 0xf0, 0xde, 0xfe, + 0x04, 0xac, 0x06, 0x00, 0x3f, 0x28, 0x09, 0xd9, 0x01, 0x30, 0x02, 0xf0, + 0x83, 0xff, 0x2b, 0x00, 0x01, 0x9a, 0x71, 0x1c, 0x04, 0x00, 0x03, 0x95, + 0x07, 0xf0, 0xd0, 0xfe, 0x3b, 0x68, 0x32, 0x00, 0x5b, 0x68, 0x21, 0x00, + 0x38, 0x00, 0x98, 0x47, 0x04, 0xab, 0x05, 0x00, 0x9c, 0x42, 0x02, 0xd0, + 0x20, 0x00, 0x02, 0xf0, 0x73, 0xff, 0x28, 0x00, 0x14, 0xb0, 0xf0, 0xbc, + 0x08, 0xbc, 0x03, 0xb0, 0x18, 0x47, 0x10, 0xb5, 0x00, 0x28, 0x01, 0xd0, + 0x01, 0xf0, 0x24, 0xfb, 0x10, 0xbd, 0x00, 0x00, 0x30, 0xb5, 0x80, 0x24, + 0x00, 0x25, 0x04, 0x49, 0x64, 0x04, 0x0a, 0x68, 0x4b, 0x68, 0x12, 0x19, + 0x6b, 0x41, 0x0a, 0x60, 0x4b, 0x60, 0x30, 0xbd, 0x90, 0x0d, 0x00, 0x20, + 0x10, 0xb5, 0xd0, 0x24, 0xff, 0x23, 0x24, 0x06, 0x20, 0x68, 0x23, 0x65, + 0x04, 0x49, 0x0f, 0x30, 0x00, 0xf0, 0x02, 0xff, 0x20, 0x68, 0x01, 0x21, + 0x0f, 0x30, 0x00, 0xf0, 0xe5, 0xfe, 0x10, 0xbd, 0xc1, 0x00, 0x00, 0x20, + 0x08, 0x4b, 0x10, 0xb5, 0x1b, 0x78, 0x00, 0x2b, 0x01, 0xd1, 0xff, 0xf7, + 0xe7, 0xff, 0x06, 0x4b, 0x00, 0x2b, 0x01, 0xd0, 0x00, 0xe0, 0x00, 0xbf, + 0x04, 0x4b, 0x00, 0x2b, 0xfd, 0xd0, 0x00, 0xe0, 0x00, 0xbf, 0xf9, 0xe7, + 0xce, 0x1a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0xb5, 0x0d, 0x4c, 0x20, 0x00, 0x0c, 0x30, 0x01, 0xf0, 0x2a, 0xfd, + 0x00, 0xf0, 0x78, 0xfe, 0x03, 0x00, 0x20, 0x00, 0x08, 0x22, 0x04, 0x21, + 0x14, 0x30, 0x01, 0xf0, 0x10, 0xfd, 0x00, 0xf0, 0x6f, 0xfe, 0x03, 0x00, + 0x20, 0x00, 0x08, 0x22, 0x04, 0x21, 0x24, 0x30, 0x01, 0xf0, 0x07, 0xfd, + 0x01, 0x23, 0x23, 0x72, 0x10, 0xbd, 0xc0, 0x46, 0x90, 0x0d, 0x00, 0x20, + 0x00, 0x23, 0x00, 0x22, 0xf0, 0xb5, 0x02, 0x60, 0x43, 0x60, 0x47, 0x4b, + 0x04, 0x00, 0x1b, 0x78, 0x87, 0xb0, 0x00, 0x2b, 0x0b, 0xd1, 0x01, 0x20, + 0x44, 0x49, 0x40, 0x42, 0x01, 0xf0, 0x24, 0xfd, 0x07, 0x22, 0x43, 0x4b, + 0x1a, 0x60, 0x43, 0x4a, 0x5a, 0x60, 0x07, 0xb0, 0xf0, 0xbd, 0x0c, 0x20, + 0x02, 0xf0, 0xee, 0xfe, 0x01, 0x23, 0x5b, 0x42, 0x03, 0x60, 0x43, 0x60, + 0x3e, 0x4e, 0x3f, 0x4b, 0x05, 0x00, 0x83, 0x60, 0xe0, 0x63, 0x02, 0xa9, + 0x30, 0x00, 0x0b, 0xf0, 0xa1, 0xfa, 0x00, 0x28, 0x33, 0xd1, 0xd0, 0x23, + 0x1b, 0x06, 0x1b, 0x68, 0x02, 0x9a, 0x93, 0x42, 0x2a, 0xd1, 0x01, 0x90, + 0x37, 0x4f, 0x00, 0x21, 0x38, 0x00, 0x01, 0xf0, 0xab, 0xfd, 0x00, 0x28, + 0x28, 0xdb, 0x67, 0x63, 0x34, 0x4b, 0xa0, 0x63, 0x60, 0x6b, 0xc3, 0x18, + 0x5a, 0x42, 0x53, 0x41, 0x9b, 0x00, 0x5b, 0x59, 0x00, 0x2b, 0x0f, 0xda, + 0xa9, 0x68, 0x01, 0xf0, 0xb5, 0xfd, 0x00, 0x28, 0x1f, 0xd0, 0xa9, 0x68, + 0x60, 0x6b, 0x01, 0xf0, 0xc5, 0xfd, 0x2b, 0x4a, 0x63, 0x6b, 0x9b, 0x18, + 0x5a, 0x42, 0x53, 0x41, 0x9b, 0x00, 0xe8, 0x50, 0x27, 0x4a, 0x63, 0x6b, + 0x9b, 0x18, 0x5a, 0x42, 0x53, 0x41, 0x9b, 0x00, 0x5d, 0x59, 0x0d, 0xe0, + 0x30, 0x00, 0x0b, 0xf0, 0x93, 0xfa, 0x01, 0x23, 0x01, 0x93, 0xcf, 0xe7, + 0x21, 0x4f, 0x00, 0x21, 0x38, 0x00, 0x01, 0xf0, 0x7b, 0xfd, 0x00, 0x28, + 0xcf, 0xda, 0x00, 0x25, 0x01, 0x9b, 0x00, 0x2b, 0x02, 0xd0, 0x30, 0x00, + 0x0b, 0xf0, 0x2a, 0xfa, 0x00, 0x23, 0x05, 0x93, 0x80, 0x23, 0x5b, 0x02, + 0x02, 0x93, 0xc0, 0x23, 0x1b, 0x03, 0x04, 0x93, 0x6b, 0x1c, 0x66, 0x6b, + 0xa7, 0x6b, 0xea, 0x01, 0x1b, 0x03, 0x13, 0x43, 0x39, 0x00, 0x30, 0x00, + 0x2a, 0x00, 0x03, 0x93, 0x02, 0xab, 0x01, 0xf0, 0xab, 0xfd, 0x18, 0x23, + 0x5f, 0x43, 0x10, 0x4b, 0xf6, 0x19, 0xd8, 0x36, 0x33, 0x60, 0x0f, 0x4b, + 0xa0, 0x6b, 0x33, 0x60, 0x01, 0x23, 0x83, 0x40, 0x62, 0x6b, 0x11, 0x68, + 0x0b, 0x43, 0x13, 0x60, 0x81, 0xe7, 0xc0, 0x46, 0xce, 0x1a, 0x00, 0x20, + 0x4d, 0x46, 0x00, 0x10, 0x10, 0xe0, 0x00, 0xe0, 0xff, 0xff, 0xff, 0x00, + 0xc4, 0x12, 0x00, 0x20, 0x7a, 0xfd, 0x00, 0x10, 0x00, 0x00, 0x20, 0x50, + 0x00, 0x00, 0xd0, 0xaf, 0x00, 0x00, 0x30, 0x50, 0x20, 0xe0, 0x00, 0x00, + 0x40, 0xe0, 0x00, 0x00, 0x70, 0x47, 0x00, 0x00, 0x08, 0x4b, 0x10, 0xb5, + 0x00, 0x2b, 0x01, 0xd0, 0xff, 0xf7, 0xa2, 0xfe, 0x06, 0x4b, 0x00, 0x2b, + 0x01, 0xd0, 0x00, 0xe0, 0x00, 0xbf, 0x05, 0x4b, 0x00, 0x2b, 0x01, 0xd0, + 0x00, 0xe0, 0x00, 0xbf, 0x10, 0xbd, 0xc0, 0x46, 0xa1, 0x45, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x23, 0x1b, 0x06, + 0x1b, 0x68, 0x00, 0x2b, 0x02, 0xd1, 0x02, 0x4b, 0x18, 0x68, 0x70, 0x47, + 0x01, 0x4b, 0xfb, 0xe7, 0x9c, 0x05, 0x00, 0x20, 0x3c, 0x0e, 0x00, 0x20, + 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x02, 0x4b, 0x18, 0x60, 0x59, 0x60, + 0x1a, 0x72, 0x70, 0x47, 0x90, 0x0d, 0x00, 0x20, 0x7f, 0xb5, 0x3b, 0x48, + 0x03, 0xab, 0x02, 0xaa, 0x01, 0xa9, 0x01, 0xf0, 0xfd, 0xfd, 0x00, 0x28, + 0x61, 0xd0, 0x03, 0x9a, 0x02, 0x99, 0x01, 0x98, 0x01, 0xf0, 0xba, 0xfd, + 0x35, 0x4b, 0x01, 0x22, 0x35, 0x4d, 0x00, 0x2b, 0x00, 0xd1, 0x1a, 0x1c, + 0x2a, 0x70, 0x00, 0x2b, 0x16, 0xd1, 0x33, 0x4b, 0x00, 0x2b, 0x02, 0xd1, + 0x32, 0x4b, 0x00, 0x2b, 0x10, 0xd0, 0x01, 0x21, 0xf0, 0x20, 0x05, 0xf0, + 0x8a, 0xf8, 0x04, 0x00, 0x2f, 0x4b, 0xf0, 0x22, 0x00, 0x21, 0x18, 0x60, + 0x02, 0xf0, 0xf8, 0xfd, 0x2d, 0x4b, 0x63, 0x60, 0x2d, 0x4b, 0xa3, 0x60, + 0x2d, 0x4b, 0xe3, 0x60, 0x2d, 0x48, 0x01, 0xf0, 0x05, 0xfc, 0x2d, 0x4e, + 0x30, 0x00, 0xff, 0xf7, 0xef, 0xfe, 0xff, 0xf7, 0x97, 0xff, 0x2b, 0x78, + 0x00, 0x2b, 0x01, 0xd0, 0x00, 0xe0, 0x00, 0xbf, 0x00, 0xf0, 0xf8, 0xfc, + 0x2b, 0x78, 0x00, 0x2b, 0x2f, 0xd1, 0xe1, 0x21, 0x25, 0x48, 0x49, 0x02, + 0xff, 0xf7, 0xa7, 0xfc, 0x2b, 0x78, 0x00, 0x2b, 0x27, 0xd1, 0x1a, 0x4c, + 0x00, 0x2c, 0x02, 0xd1, 0x19, 0x4b, 0x00, 0x2b, 0x1f, 0xd0, 0xff, 0xf7, + 0xb5, 0xfe, 0x2b, 0x78, 0x00, 0x2b, 0x1c, 0xd1, 0xff, 0xf7, 0x86, 0xfe, + 0x2b, 0x78, 0x00, 0x2b, 0x17, 0xd1, 0x00, 0x2c, 0x02, 0xd1, 0x12, 0x4b, + 0x00, 0x2b, 0x05, 0xd0, 0x01, 0x20, 0xff, 0xf7, 0x66, 0xfe, 0x17, 0x48, + 0x02, 0xf0, 0x46, 0xfe, 0xff, 0xf7, 0x78, 0xfc, 0xff, 0xf7, 0x56, 0xfc, + 0xff, 0xf7, 0x66, 0xff, 0xfa, 0xe7, 0x06, 0x49, 0x12, 0x48, 0x01, 0xf0, + 0x75, 0xfe, 0x34, 0x72, 0xe2, 0xe7, 0xff, 0xf7, 0x93, 0xfe, 0x00, 0xe0, + 0x00, 0xbf, 0x00, 0x20, 0x04, 0xb0, 0x70, 0xbd, 0x88, 0x07, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xce, 0x1a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x3c, 0x0e, 0x00, 0x20, 0x78, 0x01, 0x01, 0x10, + 0x58, 0x01, 0x01, 0x10, 0x38, 0x01, 0x01, 0x10, 0xc4, 0x12, 0x00, 0x20, + 0x90, 0x0d, 0x00, 0x20, 0x24, 0x0e, 0x00, 0x20, 0x8d, 0x46, 0x00, 0x10, + 0x48, 0xfd, 0x00, 0x10, 0x83, 0x69, 0xc2, 0x69, 0x93, 0x42, 0x05, 0xd1, + 0x80, 0x22, 0x43, 0x6a, 0x92, 0x00, 0x04, 0x3b, 0x1b, 0x68, 0x9b, 0x18, + 0x18, 0x1f, 0x70, 0x47, 0xd0, 0x23, 0x70, 0xb5, 0x28, 0x24, 0x1b, 0x06, + 0x1b, 0x68, 0x5c, 0x43, 0x11, 0x4b, 0x1c, 0x19, 0xa5, 0x69, 0xa3, 0x68, + 0x9d, 0x42, 0x0a, 0xd0, 0x20, 0x00, 0xff, 0xf7, 0xe5, 0xff, 0xe3, 0x69, + 0x06, 0x68, 0x9d, 0x42, 0x04, 0xd0, 0x04, 0x3d, 0xa5, 0x61, 0x86, 0xf3, + 0x10, 0x88, 0x70, 0xbd, 0x80, 0x21, 0x28, 0x00, 0x89, 0x00, 0x02, 0xf0, + 0x7b, 0xfd, 0x80, 0x22, 0x63, 0x6a, 0x92, 0x00, 0x04, 0x3b, 0x63, 0x62, + 0x1b, 0x68, 0x9a, 0x18, 0xe3, 0x61, 0xfd, 0x33, 0xff, 0x33, 0x22, 0x62, + 0xa3, 0x61, 0xea, 0xe7, 0x64, 0x0e, 0x00, 0x20, 0xd0, 0x23, 0xf0, 0xb5, + 0x1b, 0x06, 0x1b, 0x68, 0x87, 0xb0, 0x01, 0x93, 0xef, 0xf3, 0x10, 0x83, + 0x03, 0x93, 0x72, 0xb6, 0x50, 0x4b, 0x28, 0x20, 0x9c, 0x46, 0x01, 0x9b, + 0x58, 0x43, 0x63, 0x46, 0x1d, 0x18, 0x2a, 0x6a, 0xab, 0x69, 0x04, 0x3a, + 0x93, 0x42, 0x04, 0xd0, 0x03, 0x9a, 0x04, 0xc3, 0xab, 0x61, 0x07, 0xb0, + 0xf0, 0xbd, 0x6a, 0x6a, 0x69, 0x69, 0xac, 0x68, 0x56, 0x1a, 0xb7, 0x10, + 0x04, 0x96, 0xee, 0x69, 0x9b, 0x1b, 0x7e, 0x1e, 0x9b, 0x10, 0xf6, 0x01, + 0x9e, 0x19, 0x2b, 0x69, 0x1b, 0x1b, 0x9b, 0x10, 0xf3, 0x18, 0x41, 0x4e, + 0xb3, 0x42, 0x02, 0xd1, 0x40, 0x48, 0x04, 0xf0, 0xa4, 0xff, 0x64, 0x46, + 0x04, 0x59, 0x6b, 0x68, 0x10, 0x1b, 0x80, 0x10, 0x18, 0x1a, 0x01, 0x28, + 0x1c, 0xd8, 0x02, 0x37, 0x78, 0x00, 0x83, 0x42, 0x3a, 0xd9, 0xdb, 0x1b, + 0x5b, 0x08, 0x9b, 0x00, 0xe4, 0x18, 0x13, 0x1d, 0x5a, 0x1a, 0xa1, 0x42, + 0x29, 0xd9, 0x20, 0x00, 0x99, 0x42, 0x2c, 0xd1, 0x80, 0x22, 0x23, 0x68, + 0x92, 0x00, 0xeb, 0x60, 0x9b, 0x18, 0x2b, 0x61, 0x04, 0x9b, 0x6c, 0x61, + 0xe4, 0x18, 0x23, 0x68, 0x6c, 0x62, 0xeb, 0x61, 0x9b, 0x18, 0x2b, 0x62, + 0x28, 0x24, 0x80, 0x20, 0x01, 0x9b, 0x80, 0x00, 0x5c, 0x43, 0x28, 0x4b, + 0x1c, 0x19, 0x66, 0x6a, 0x02, 0xf0, 0x00, 0xfd, 0x70, 0x60, 0xa3, 0x69, + 0x03, 0x9a, 0x1a, 0x60, 0x63, 0x6a, 0x1a, 0x1d, 0x6a, 0x62, 0x80, 0x22, + 0x5b, 0x68, 0x92, 0x00, 0x9a, 0x18, 0xeb, 0x61, 0x2a, 0x62, 0xa3, 0x61, + 0xa9, 0xe7, 0x99, 0x42, 0xd6, 0xd0, 0x04, 0x9b, 0x18, 0x1d, 0x80, 0x1a, + 0x20, 0x18, 0x0b, 0xf0, 0xd9, 0xf8, 0xcf, 0xe7, 0x9e, 0x1c, 0x00, 0x2b, + 0x00, 0xd1, 0x01, 0x33, 0xf6, 0x18, 0x80, 0x23, 0x9b, 0x05, 0x9e, 0x42, + 0x01, 0xd3, 0x04, 0xf0, 0x4f, 0xff, 0xb0, 0x00, 0x02, 0xf0, 0xda, 0xfc, + 0x28, 0x22, 0x01, 0x9b, 0xf4, 0x1b, 0x5a, 0x43, 0x10, 0x4b, 0x64, 0x08, + 0x9b, 0x18, 0x5a, 0x6a, 0x59, 0x69, 0xa4, 0x00, 0x04, 0x32, 0x05, 0x90, + 0x04, 0x19, 0x91, 0x42, 0x03, 0xd0, 0x20, 0x00, 0x52, 0x1a, 0x0b, 0xf0, + 0xb7, 0xf8, 0x28, 0x23, 0x01, 0x9a, 0x5a, 0x43, 0x07, 0x4b, 0x02, 0x92, + 0x9f, 0x18, 0x7b, 0x68, 0x99, 0x00, 0x05, 0x4b, 0xd0, 0x58, 0x02, 0xf0, + 0xc7, 0xfc, 0x03, 0x4b, 0x02, 0x9a, 0x05, 0x99, 0x7e, 0x60, 0xd1, 0x50, + 0x9c, 0xe7, 0xc0, 0x46, 0x64, 0x0e, 0x00, 0x20, 0xff, 0xff, 0xff, 0x1f, + 0x84, 0xfd, 0x00, 0x10, 0xf8, 0xb5, 0x80, 0x27, 0x18, 0x4c, 0xbf, 0x00, + 0x00, 0x25, 0x08, 0x23, 0x25, 0x60, 0x63, 0x60, 0xa5, 0x60, 0xe5, 0x60, + 0x25, 0x61, 0x65, 0x61, 0xa5, 0x61, 0xe5, 0x61, 0x25, 0x62, 0x65, 0x62, + 0x20, 0x20, 0x02, 0xf0, 0x9b, 0xfc, 0x63, 0x68, 0x20, 0x60, 0x01, 0x3b, + 0x5b, 0x08, 0x9b, 0x00, 0xc6, 0x18, 0x38, 0x00, 0x02, 0xf0, 0x92, 0xfc, + 0x80, 0x23, 0x9b, 0x00, 0xc3, 0x18, 0x23, 0x61, 0x23, 0x62, 0x0a, 0x4b, + 0x66, 0x61, 0xe0, 0x60, 0x66, 0x62, 0xe0, 0x61, 0xa0, 0x60, 0xa0, 0x61, + 0x28, 0x34, 0x30, 0x60, 0xa3, 0x42, 0xd7, 0xd1, 0x05, 0x4b, 0x1a, 0x1d, + 0x1d, 0x71, 0x9d, 0x60, 0x5d, 0x61, 0xda, 0x60, 0x1a, 0x61, 0xf8, 0xbd, + 0x64, 0x0e, 0x00, 0x20, 0xb4, 0x0e, 0x00, 0x20, 0x4c, 0x0e, 0x00, 0x20, + 0x04, 0x4b, 0x10, 0xb5, 0x18, 0x68, 0x00, 0xf0, 0x1b, 0xfc, 0xfa, 0x20, + 0x00, 0x21, 0x80, 0x00, 0x10, 0xbd, 0xc0, 0x46, 0x44, 0x0e, 0x00, 0x20, + 0x10, 0xb5, 0x06, 0x4c, 0x00, 0x21, 0x20, 0x00, 0x0b, 0xf0, 0x22, 0xf8, + 0x00, 0x28, 0x04, 0xd0, 0x02, 0xf0, 0x4c, 0xff, 0x20, 0x00, 0x0a, 0xf0, + 0xeb, 0xff, 0x10, 0xbd, 0xb4, 0x0e, 0x00, 0x20, 0x3f, 0x21, 0x10, 0xb5, + 0x02, 0x4b, 0x03, 0x4a, 0x03, 0x48, 0x01, 0xf0, 0xf1, 0xfc, 0xc0, 0x46, + 0xb4, 0xfd, 0x00, 0x10, 0xcf, 0xfd, 0x00, 0x10, 0x05, 0xfe, 0x00, 0x10, + 0x30, 0xb5, 0x23, 0x4c, 0x23, 0x4b, 0x24, 0x4d, 0x24, 0x49, 0x25, 0x4a, + 0x25, 0x48, 0x00, 0x2c, 0x08, 0xd0, 0x00, 0x2b, 0x08, 0xd1, 0x00, 0x2d, + 0x12, 0xd1, 0x00, 0x29, 0x0e, 0xd1, 0x00, 0x2a, 0x0c, 0xd1, 0x30, 0xbd, + 0x00, 0x2b, 0x09, 0xd0, 0xc3, 0x7a, 0x84, 0x7a, 0x1b, 0x02, 0x23, 0x43, + 0x80, 0x24, 0x24, 0x02, 0x1c, 0x43, 0x24, 0x0a, 0x83, 0x72, 0xc4, 0x72, + 0x00, 0x2d, 0x09, 0xd0, 0xc3, 0x7a, 0x84, 0x7a, 0x1b, 0x02, 0x23, 0x43, + 0x80, 0x24, 0xe4, 0x01, 0x1c, 0x43, 0x24, 0x0a, 0x83, 0x72, 0xc4, 0x72, + 0x00, 0x29, 0x09, 0xd0, 0xc3, 0x7a, 0x81, 0x7a, 0x1b, 0x02, 0x0b, 0x43, + 0x80, 0x21, 0x49, 0x00, 0x19, 0x43, 0x09, 0x0a, 0x83, 0x72, 0xc1, 0x72, + 0x00, 0x2a, 0x09, 0xd0, 0xc3, 0x7a, 0x82, 0x7a, 0x1b, 0x02, 0x13, 0x43, + 0x80, 0x22, 0x92, 0x01, 0x1a, 0x43, 0x12, 0x0a, 0x83, 0x72, 0xc2, 0x72, + 0x00, 0x23, 0x03, 0x71, 0x43, 0x71, 0x83, 0x71, 0xc9, 0xe7, 0xc0, 0x46, + 0x69, 0x45, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc4, 0x04, 0x00, 0x20, + 0xf0, 0xb5, 0x8d, 0x4c, 0xbd, 0xb0, 0x21, 0x00, 0x4f, 0x22, 0x14, 0xa8, + 0x02, 0xf0, 0xe8, 0xfb, 0x21, 0x00, 0x43, 0x22, 0x4f, 0x31, 0x03, 0xa8, + 0x02, 0xf0, 0xe2, 0xfb, 0x87, 0x4c, 0x26, 0x1e, 0x00, 0xd0, 0x43, 0x26, + 0x86, 0x4b, 0x87, 0x4f, 0x00, 0x2b, 0x05, 0xd0, 0x86, 0x4b, 0x4f, 0x36, + 0x00, 0x2b, 0x05, 0xd1, 0x35, 0x00, 0x05, 0xe0, 0x83, 0x4b, 0x00, 0x2b, + 0x00, 0xd1, 0xef, 0xe0, 0x35, 0x00, 0x44, 0x35, 0x28, 0x00, 0x05, 0xf0, + 0x04, 0xf8, 0x01, 0x90, 0x38, 0x60, 0x00, 0x28, 0x00, 0xd1, 0xeb, 0xe0, + 0x7d, 0x4b, 0x1d, 0x60, 0x00, 0x2c, 0x03, 0xd0, 0x43, 0x22, 0x03, 0xa9, + 0x02, 0xf0, 0xbe, 0xfb, 0x76, 0x4b, 0x00, 0x2b, 0x0e, 0xd0, 0x00, 0x2c, + 0x00, 0xd1, 0xdf, 0xe0, 0x77, 0x49, 0x4f, 0x22, 0x12, 0x31, 0x28, 0xa8, + 0x02, 0xf0, 0xb2, 0xfb, 0x4f, 0x22, 0x01, 0x98, 0x28, 0xa9, 0x43, 0x30, + 0x02, 0xf0, 0xac, 0xfb, 0x6f, 0x4b, 0x00, 0x2b, 0x00, 0xd1, 0xcd, 0xe0, + 0x63, 0x1e, 0x9c, 0x41, 0x6a, 0x4b, 0x00, 0x21, 0x5a, 0x1e, 0x93, 0x41, + 0x32, 0xa8, 0x13, 0x22, 0x01, 0x34, 0xe4, 0x18, 0x02, 0xf0, 0x96, 0xfb, + 0xa1, 0x20, 0x01, 0x23, 0x28, 0xad, 0x28, 0x71, 0x1c, 0x38, 0xa8, 0x71, + 0x55, 0x38, 0xe8, 0x72, 0xc0, 0x18, 0x68, 0x73, 0xc0, 0x18, 0xe8, 0x73, + 0x33, 0x20, 0xec, 0x71, 0x35, 0x24, 0x09, 0x22, 0x05, 0x21, 0x81, 0x27, + 0xe8, 0x74, 0xc0, 0x18, 0x68, 0x75, 0x1f, 0x38, 0xa8, 0x75, 0x10, 0x30, + 0x28, 0x76, 0x5a, 0x30, 0x68, 0x76, 0x16, 0x30, 0xa8, 0x76, 0x8f, 0x38, + 0xe8, 0x76, 0x6f, 0x30, 0x28, 0x77, 0x6d, 0x38, 0x68, 0x77, 0x06, 0x38, + 0x84, 0x46, 0x6c, 0x74, 0xe8, 0x77, 0x02, 0xac, 0x97, 0x30, 0x00, 0x19, + 0x29, 0x70, 0x6b, 0x70, 0xaa, 0x70, 0xe9, 0x70, 0x6b, 0x71, 0x29, 0x72, + 0x6b, 0x72, 0xaa, 0x72, 0x2a, 0x73, 0xaa, 0x73, 0x2a, 0x74, 0xaa, 0x74, + 0x2a, 0x75, 0xef, 0x75, 0xaf, 0x77, 0xc1, 0x77, 0x9a, 0x20, 0x00, 0x19, + 0xc3, 0x77, 0x9b, 0x20, 0x00, 0x19, 0x39, 0x24, 0xc2, 0x77, 0x29, 0xa8, + 0xc4, 0x77, 0x9d, 0x20, 0x02, 0xac, 0x00, 0x19, 0x15, 0x24, 0xc4, 0x77, + 0x9e, 0x20, 0x02, 0xac, 0x00, 0x19, 0xc3, 0x77, 0x9f, 0x20, 0x00, 0x19, + 0x25, 0x24, 0xc4, 0x77, 0x2a, 0xa8, 0x1d, 0x3c, 0xc4, 0x77, 0x02, 0xa8, + 0xb8, 0x34, 0x00, 0x19, 0x8b, 0x3c, 0x04, 0x70, 0xc2, 0x20, 0x02, 0xac, + 0x00, 0x19, 0x46, 0x24, 0x04, 0x70, 0xc3, 0x20, 0x02, 0xac, 0x00, 0x19, + 0x3b, 0x24, 0x04, 0x70, 0x33, 0xa8, 0x03, 0x70, 0xc5, 0x20, 0x02, 0xac, + 0x00, 0x19, 0x95, 0x24, 0x04, 0x70, 0xc6, 0x20, 0x02, 0xac, 0x00, 0x19, + 0x03, 0x70, 0xc7, 0x20, 0x00, 0x19, 0x75, 0x24, 0x04, 0x70, 0x34, 0xa8, + 0x6d, 0x3c, 0x04, 0x70, 0xc9, 0x20, 0x02, 0xac, 0x00, 0x19, 0x07, 0x70, + 0xca, 0x20, 0x00, 0x19, 0x64, 0x46, 0x04, 0x70, 0xcb, 0x20, 0x02, 0xac, + 0x00, 0x19, 0x01, 0x70, 0x35, 0xa9, 0x0a, 0x70, 0x19, 0x21, 0xc4, 0x32, + 0x12, 0x19, 0x11, 0x70, 0xce, 0x22, 0x12, 0x19, 0x13, 0x70, 0xcf, 0x22, + 0x29, 0x21, 0x12, 0x19, 0x11, 0x70, 0x20, 0x22, 0x36, 0xa9, 0x0a, 0x70, + 0xd1, 0x21, 0x09, 0x19, 0x15, 0x24, 0x0c, 0x70, 0xd3, 0x21, 0x02, 0xa8, + 0x09, 0x18, 0x10, 0x34, 0x0c, 0x70, 0x37, 0xa9, 0x0b, 0x70, 0xd5, 0x21, + 0x02, 0xa8, 0x09, 0x18, 0x70, 0x34, 0x0c, 0x70, 0xd6, 0x21, 0x02, 0xa8, + 0x09, 0x18, 0x0a, 0x70, 0xb7, 0x32, 0x12, 0x18, 0x20, 0x3c, 0x14, 0x70, + 0x38, 0xaa, 0x13, 0x70, 0xd8, 0x33, 0x1b, 0x18, 0x1f, 0x70, 0xda, 0x23, + 0x62, 0x46, 0x1b, 0x18, 0x1a, 0x70, 0xdb, 0x23, 0xc0, 0x22, 0x1b, 0x18, + 0x1a, 0x70, 0x01, 0x9b, 0x29, 0x00, 0x98, 0x19, 0x7c, 0x3a, 0x02, 0xf0, + 0xe1, 0xfa, 0x05, 0xe0, 0x00, 0x2e, 0x00, 0xd0, 0x06, 0xe7, 0x09, 0x4b, + 0x3e, 0x60, 0x1e, 0x60, 0x3d, 0xb0, 0xf0, 0xbd, 0x4f, 0x22, 0x01, 0x98, + 0x14, 0xa9, 0x25, 0xe7, 0x85, 0xfe, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x38, 0x0e, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x48, 0x0e, 0x00, 0x20, 0x05, 0xff, 0x00, 0x10, 0x01, 0x4b, 0x18, 0x68, + 0x70, 0x47, 0xc0, 0x46, 0x38, 0x0e, 0x00, 0x20, 0x01, 0x4b, 0x18, 0x68, + 0x70, 0x47, 0xc0, 0x46, 0x40, 0x0e, 0x00, 0x20, 0xf0, 0xb5, 0xc2, 0x4b, + 0xb9, 0xb0, 0x1b, 0x68, 0x00, 0x2b, 0x00, 0xd0, 0x67, 0xe1, 0xc0, 0x4b, + 0xc0, 0x4e, 0x00, 0x2b, 0x00, 0xd0, 0x6f, 0xe1, 0xbf, 0x4b, 0x00, 0x2b, + 0x00, 0xd0, 0x6b, 0xe1, 0xbe, 0x4d, 0x00, 0x2d, 0x00, 0xd0, 0x6c, 0xe1, + 0x02, 0x23, 0x01, 0x93, 0x2b, 0x00, 0x00, 0x2e, 0x05, 0xd1, 0x01, 0x96, + 0x02, 0xe0, 0x02, 0x23, 0x01, 0x25, 0x01, 0x93, 0x2b, 0x00, 0x01, 0x9a, + 0x9b, 0x18, 0xb7, 0x4a, 0xdb, 0xb2, 0x03, 0x93, 0x02, 0x23, 0x00, 0x2a, + 0x00, 0xd1, 0x13, 0x00, 0x03, 0x9a, 0xb4, 0x49, 0xd3, 0x18, 0xdb, 0xb2, + 0x42, 0x22, 0x61, 0x31, 0x10, 0xa8, 0x02, 0x93, 0x02, 0xf0, 0x88, 0xfa, + 0xb0, 0x4b, 0x09, 0xac, 0x1b, 0x68, 0x19, 0x22, 0x00, 0x21, 0x20, 0x00, + 0x04, 0x93, 0x02, 0xf0, 0x79, 0xfa, 0x5c, 0x22, 0x00, 0x21, 0x21, 0xa8, + 0x02, 0xf0, 0x74, 0xfa, 0x4b, 0x27, 0x00, 0x2e, 0x00, 0xd1, 0x42, 0x3f, + 0x19, 0x23, 0x6a, 0x42, 0x13, 0x40, 0xa4, 0x4a, 0xff, 0x18, 0x5c, 0x23, + 0x00, 0x2a, 0x00, 0xd1, 0x13, 0x00, 0xff, 0x18, 0x09, 0x22, 0x00, 0x21, + 0x06, 0xa8, 0x02, 0xf0, 0x61, 0xfa, 0xfb, 0xb2, 0x38, 0x00, 0x05, 0x93, + 0x04, 0xf0, 0x9b, 0xfe, 0x96, 0x4b, 0x06, 0x1e, 0x18, 0x60, 0x00, 0xd1, + 0x11, 0xe1, 0x3a, 0x00, 0x00, 0x21, 0x02, 0xf0, 0x53, 0xfa, 0x09, 0x22, + 0x06, 0xab, 0x1a, 0x70, 0x02, 0x23, 0x06, 0xaa, 0x53, 0x70, 0x13, 0x00, + 0x05, 0x9a, 0x30, 0x00, 0x9a, 0x70, 0x02, 0x9a, 0x06, 0xa9, 0x1a, 0x71, + 0x01, 0x23, 0x06, 0xaa, 0x53, 0x71, 0x9f, 0x33, 0xd3, 0x71, 0x23, 0x3b, + 0x13, 0x72, 0x09, 0x22, 0x02, 0xf0, 0x42, 0xfa, 0x30, 0x00, 0x88, 0x4b, + 0x09, 0x30, 0x00, 0x2b, 0x00, 0xd0, 0xf6, 0xe0, 0x02, 0x90, 0x00, 0x2d, + 0x29, 0xd0, 0x04, 0x23, 0x63, 0x70, 0x01, 0x9b, 0x09, 0x21, 0xa3, 0x70, + 0x01, 0x23, 0x23, 0x71, 0x23, 0x73, 0xa3, 0x73, 0x21, 0x33, 0xe3, 0x73, + 0x04, 0x9b, 0x03, 0x22, 0x23, 0x74, 0x1b, 0x12, 0x63, 0x74, 0x07, 0x23, + 0xa3, 0x74, 0x02, 0x3b, 0xe3, 0x74, 0x7e, 0x33, 0x21, 0x70, 0x61, 0x72, + 0x23, 0x75, 0x18, 0x31, 0x43, 0x3b, 0xa1, 0x72, 0xa3, 0x75, 0x10, 0x39, + 0x36, 0x3b, 0x62, 0x71, 0xe1, 0x72, 0x62, 0x75, 0x23, 0x76, 0x21, 0x00, + 0x02, 0x98, 0x16, 0x32, 0x02, 0xf0, 0x12, 0xfa, 0x02, 0x9b, 0x19, 0x33, + 0x02, 0x93, 0x72, 0x4b, 0x00, 0x2b, 0x00, 0xd1, 0xbf, 0xe0, 0x04, 0x25, + 0x03, 0x27, 0x6d, 0x24, 0x21, 0xa9, 0x4d, 0x70, 0x00, 0x95, 0xcd, 0x74, + 0x0f, 0x76, 0x7f, 0x19, 0x06, 0xad, 0x64, 0x19, 0xcf, 0x76, 0x27, 0x00, + 0x25, 0x24, 0xfc, 0x77, 0x06, 0x27, 0x24, 0x26, 0x03, 0x9b, 0x4a, 0x34, + 0x64, 0x19, 0xe7, 0x77, 0x5a, 0x1c, 0x22, 0xac, 0xe6, 0x77, 0xd2, 0xb2, + 0x71, 0x24, 0x4a, 0x74, 0x0a, 0x75, 0x02, 0x22, 0x03, 0x9b, 0x64, 0x19, + 0xe2, 0x77, 0x72, 0x24, 0x8b, 0x70, 0x01, 0x23, 0x64, 0x19, 0xe3, 0x77, + 0x73, 0x24, 0x64, 0x19, 0xe3, 0x77, 0x2b, 0xac, 0x27, 0x70, 0x95, 0x24, + 0x64, 0x19, 0x27, 0x00, 0x34, 0x00, 0x09, 0x20, 0x72, 0x34, 0x64, 0x19, + 0x08, 0x70, 0x4b, 0x71, 0x8b, 0x71, 0x48, 0x72, 0x8e, 0x72, 0xcb, 0x72, + 0x4b, 0x73, 0x88, 0x73, 0x0b, 0x74, 0x88, 0x74, 0x8a, 0x75, 0xcb, 0x75, + 0x0e, 0x77, 0x4b, 0x77, 0xcb, 0x77, 0x3e, 0x70, 0x22, 0x70, 0x97, 0x24, + 0x64, 0x19, 0x22, 0x70, 0x9a, 0x24, 0x64, 0x19, 0x20, 0x70, 0x9b, 0x24, + 0x2c, 0xaf, 0x64, 0x19, 0x3a, 0x70, 0x27, 0x00, 0x24, 0x24, 0x3c, 0x70, + 0x9d, 0x24, 0x64, 0x19, 0x23, 0x70, 0x9e, 0x24, 0x03, 0x26, 0x64, 0x19, + 0x26, 0x70, 0x9f, 0x24, 0x64, 0x19, 0x23, 0x70, 0xa1, 0x24, 0x64, 0x19, + 0x23, 0x70, 0xa3, 0x24, 0x64, 0x19, 0x20, 0x70, 0x24, 0x24, 0x2d, 0xaf, + 0x3e, 0x70, 0x2e, 0xaf, 0x3a, 0x70, 0x2f, 0xaf, 0x3c, 0x70, 0x81, 0x34, + 0x64, 0x19, 0x26, 0x70, 0xa6, 0x24, 0x64, 0x19, 0x22, 0x70, 0xa7, 0x24, + 0x04, 0x27, 0x64, 0x19, 0x27, 0x70, 0x30, 0xac, 0x23, 0x70, 0xa9, 0x24, + 0x64, 0x19, 0x23, 0x70, 0xaa, 0x24, 0x64, 0x19, 0x23, 0x70, 0x31, 0xac, + 0x20, 0x70, 0x05, 0x24, 0xa9, 0x37, 0x7f, 0x19, 0x3c, 0x70, 0xae, 0x27, + 0x7f, 0x19, 0x3b, 0x70, 0xaf, 0x27, 0x7f, 0x19, 0x40, 0x25, 0x3a, 0x70, + 0x32, 0xaf, 0x3d, 0x70, 0xb5, 0x27, 0x06, 0xad, 0x7f, 0x19, 0x3c, 0x70, + 0xb6, 0x27, 0x7f, 0x19, 0x3d, 0x00, 0x25, 0x27, 0x2f, 0x70, 0x06, 0xad, + 0x92, 0x37, 0x7f, 0x19, 0x3b, 0x70, 0xb9, 0x27, 0x34, 0xad, 0x2b, 0x70, + 0x06, 0xad, 0x7f, 0x19, 0x3b, 0x70, 0xba, 0x27, 0x06, 0xad, 0x7f, 0x19, + 0x38, 0x70, 0x06, 0xad, 0xb2, 0x30, 0x40, 0x19, 0x81, 0x25, 0x04, 0x70, + 0x35, 0xa8, 0x05, 0x70, 0xbd, 0x20, 0x06, 0xad, 0x40, 0x19, 0x02, 0x70, + 0x40, 0x20, 0xbc, 0x32, 0x52, 0x19, 0x10, 0x70, 0xc3, 0x22, 0x25, 0x27, + 0x52, 0x19, 0x14, 0x70, 0x37, 0xaa, 0x17, 0x70, 0xc5, 0x22, 0x52, 0x19, + 0x13, 0x70, 0xc6, 0x22, 0x52, 0x19, 0x13, 0x70, 0xc6, 0x33, 0x5b, 0x19, + 0x5c, 0x22, 0x02, 0x98, 0x1e, 0x70, 0x02, 0xf0, 0x4b, 0xf9, 0x39, 0xb0, + 0xf0, 0xbd, 0x02, 0x23, 0x01, 0x93, 0x01, 0x25, 0xa8, 0xe6, 0x42, 0x22, + 0x10, 0xa9, 0x4b, 0x36, 0x02, 0xf0, 0x40, 0xf9, 0x02, 0x96, 0x02, 0xe7, + 0x00, 0x2e, 0x00, 0xd0, 0x9b, 0xe6, 0x01, 0x96, 0xf1, 0xe7, 0x00, 0x2e, + 0xed, 0xd1, 0x01, 0x25, 0x93, 0xe6, 0xc0, 0x46, 0x40, 0x0e, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x69, 0x45, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0xff, 0x00, 0x10, + 0x48, 0x0e, 0x00, 0x20, 0x10, 0xb5, 0x04, 0x00, 0x14, 0x48, 0x03, 0x78, + 0x00, 0x2b, 0x02, 0xd1, 0x11, 0x21, 0x01, 0xf0, 0x9b, 0xf8, 0x00, 0x2c, + 0x0c, 0xd1, 0x11, 0x4b, 0x11, 0x4a, 0x5a, 0x80, 0x01, 0x23, 0xc0, 0x22, + 0x01, 0x33, 0xdb, 0xb2, 0x0d, 0x48, 0x5b, 0x00, 0x92, 0x00, 0x13, 0x43, + 0x03, 0x80, 0x10, 0xbd, 0x00, 0x20, 0x04, 0x2c, 0xfb, 0xd8, 0x02, 0x00, + 0x0a, 0x4b, 0xa4, 0x00, 0xe4, 0x58, 0x07, 0x49, 0xa0, 0x5c, 0xd3, 0xb2, + 0x00, 0x28, 0xea, 0xd0, 0x01, 0x32, 0x48, 0x80, 0x02, 0x31, 0x13, 0x2a, + 0xf6, 0xd1, 0x13, 0x00, 0xe3, 0xe7, 0xc0, 0x46, 0xbd, 0x1a, 0x00, 0x20, + 0x94, 0x1a, 0x00, 0x20, 0x09, 0x04, 0x00, 0x00, 0xa8, 0xff, 0x00, 0x10, + 0xf0, 0xb5, 0x85, 0xb0, 0x03, 0xf0, 0x5d, 0xfb, 0x05, 0x1e, 0x2d, 0xd1, + 0xff, 0xf7, 0xf8, 0xfc, 0xff, 0xf7, 0x2c, 0xfe, 0x15, 0x48, 0x00, 0xf0, + 0xf3, 0xfe, 0x03, 0xf0, 0x4d, 0xfb, 0x01, 0x20, 0x00, 0xf0, 0xd6, 0xf9, + 0x12, 0x4c, 0x13, 0x49, 0x20, 0x60, 0x00, 0xf0, 0x9b, 0xf8, 0x01, 0x21, + 0x20, 0x68, 0x00, 0xf0, 0x7f, 0xf8, 0x00, 0xf0, 0x97, 0xfb, 0x04, 0x00, + 0x00, 0xf0, 0x18, 0xfd, 0x06, 0x00, 0x0f, 0x1e, 0x01, 0xda, 0xff, 0xf7, + 0x79, 0xfc, 0xfa, 0x22, 0x00, 0x23, 0x92, 0x00, 0x92, 0x19, 0x7b, 0x41, + 0x00, 0x2b, 0xf6, 0xdb, 0x01, 0x21, 0x02, 0x91, 0x06, 0x49, 0x20, 0x00, + 0x01, 0x95, 0x00, 0x91, 0x00, 0xf0, 0x84, 0xfb, 0x05, 0xb0, 0xf0, 0xbd, + 0xb4, 0x0e, 0x00, 0x20, 0x44, 0x0e, 0x00, 0x20, 0x39, 0x4c, 0x00, 0x10, + 0x21, 0x4c, 0x00, 0x10, 0x00, 0x20, 0x70, 0x47, 0x70, 0x47, 0x00, 0x00, + 0x00, 0x21, 0x04, 0x4b, 0x04, 0x4a, 0xbf, 0xf3, 0x5f, 0x8f, 0x02, 0xc3, + 0x93, 0x42, 0xfa, 0xd1, 0x70, 0x47, 0xc0, 0x46, 0x00, 0x01, 0x00, 0xd0, + 0x80, 0x01, 0x00, 0xd0, 0x04, 0x4a, 0x10, 0x78, 0x43, 0x1c, 0xdb, 0xb2, + 0x17, 0x2b, 0x01, 0xd8, 0x13, 0x70, 0x70, 0x47, 0x10, 0x23, 0xfb, 0xe7, + 0xd6, 0x04, 0x00, 0x20, 0x07, 0xb5, 0x04, 0x4b, 0x01, 0x00, 0x00, 0x93, + 0x18, 0x22, 0x1f, 0x23, 0x02, 0x48, 0x03, 0xf0, 0x63, 0xfe, 0x0e, 0xbd, + 0xbc, 0xff, 0x00, 0x10, 0x38, 0x14, 0x00, 0x20, 0x07, 0x4b, 0x10, 0x30, + 0x9b, 0x68, 0x80, 0x00, 0xc1, 0x50, 0xbf, 0xf3, 0x5f, 0x8f, 0xbf, 0xf3, + 0x5f, 0x8f, 0x00, 0x21, 0x03, 0x4b, 0x19, 0x60, 0x82, 0xf3, 0x10, 0x88, + 0x70, 0x47, 0xc0, 0x46, 0x00, 0xed, 0x00, 0xe0, 0x24, 0x01, 0x00, 0xd0, + 0x01, 0x22, 0x82, 0x40, 0x03, 0x4b, 0x1b, 0x68, 0x13, 0x40, 0x5a, 0x1e, + 0x93, 0x41, 0xd8, 0xb2, 0x70, 0x47, 0xc0, 0x46, 0x00, 0xe1, 0x00, 0xe0, + 0x00, 0x29, 0x04, 0xd0, 0x03, 0x4b, 0x18, 0x60, 0x03, 0x4b, 0x18, 0x60, + 0x70, 0x47, 0x03, 0x4b, 0xfb, 0xe7, 0xc0, 0x46, 0x80, 0xe2, 0x00, 0xe0, + 0x00, 0xe1, 0x00, 0xe0, 0x80, 0xe1, 0x00, 0xe0, 0x01, 0x23, 0x83, 0x40, + 0x10, 0xb5, 0x18, 0x00, 0xff, 0xf7, 0xea, 0xff, 0x10, 0xbd, 0x00, 0x00, + 0x01, 0x23, 0x83, 0x40, 0x01, 0x4a, 0x13, 0x60, 0x70, 0x47, 0xc0, 0x46, + 0x00, 0xe2, 0x00, 0xe0, 0x02, 0x4b, 0x10, 0x30, 0x9b, 0x68, 0x80, 0x00, + 0xc0, 0x58, 0x70, 0x47, 0x00, 0xed, 0x00, 0xe0, 0x70, 0xb5, 0x04, 0x00, + 0x0d, 0x00, 0xef, 0xf3, 0x10, 0x86, 0x72, 0xb6, 0x0a, 0x4a, 0x13, 0x68, + 0x00, 0x2b, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x20, 0x00, 0xff, 0xf7, + 0xe9, 0xff, 0x07, 0x4b, 0x98, 0x42, 0x03, 0xd0, 0xa8, 0x42, 0x01, 0xd0, + 0x01, 0xf0, 0xfc, 0xf8, 0x32, 0x00, 0x29, 0x00, 0x20, 0x00, 0xff, 0xf7, + 0x9d, 0xff, 0x70, 0xbd, 0x24, 0x01, 0x00, 0xd0, 0xcd, 0x40, 0x00, 0x10, + 0xf0, 0xb5, 0x85, 0xb0, 0x05, 0x00, 0x01, 0x91, 0xef, 0xf3, 0x10, 0x83, + 0x02, 0x93, 0x72, 0xb6, 0x49, 0x4a, 0x13, 0x68, 0x00, 0x2b, 0xfc, 0xd0, + 0xbf, 0xf3, 0x5f, 0x8f, 0x2f, 0x00, 0x47, 0x4b, 0x10, 0x37, 0x9b, 0x68, + 0xba, 0x00, 0xd4, 0x58, 0x45, 0x4b, 0x9c, 0x42, 0x68, 0xd0, 0x01, 0x9a, + 0x94, 0x42, 0x00, 0xd1, 0x7d, 0xe0, 0x43, 0x4b, 0xe3, 0x1a, 0x2f, 0x2b, + 0x60, 0xd8, 0x28, 0x00, 0xff, 0xf7, 0x8a, 0xff, 0x00, 0x21, 0x03, 0x90, + 0x28, 0x00, 0xff, 0xf7, 0xa1, 0xff, 0xbf, 0xf3, 0x5f, 0x8f, 0xfe, 0xf7, + 0x28, 0xfe, 0x06, 0x1e, 0x03, 0xd0, 0x87, 0x42, 0x01, 0xd0, 0x01, 0xf0, + 0xc1, 0xf8, 0x01, 0x23, 0x22, 0x00, 0x9a, 0x43, 0x13, 0x00, 0x00, 0x22, + 0x35, 0x4f, 0x98, 0x68, 0x06, 0x21, 0x84, 0x46, 0x01, 0x98, 0x59, 0x56, + 0x84, 0x45, 0x14, 0xd1, 0x00, 0x29, 0x19, 0xda, 0x00, 0x2e, 0x49, 0xd1, + 0x00, 0x2a, 0x45, 0xd0, 0xff, 0x21, 0x91, 0x71, 0x2e, 0x49, 0x91, 0x80, + 0x2e, 0x49, 0x2c, 0x48, 0x0a, 0x78, 0x9a, 0x71, 0x2d, 0x4a, 0x1b, 0x1a, + 0x5b, 0x41, 0x5a, 0x43, 0x12, 0x0d, 0x0a, 0x70, 0x28, 0xe0, 0x00, 0x29, + 0x26, 0xdb, 0x0c, 0x22, 0x51, 0x43, 0x1a, 0x00, 0x7b, 0x18, 0xdc, 0xe7, + 0x0c, 0x20, 0x48, 0x43, 0x22, 0x4a, 0x16, 0x18, 0xb7, 0x68, 0x9f, 0x60, + 0xf7, 0x79, 0xdf, 0x71, 0x06, 0x27, 0xf7, 0x57, 0x9f, 0x71, 0xb7, 0x79, + 0x7f, 0x2f, 0x1e, 0xd8, 0xb6, 0x88, 0xd2, 0x1a, 0x76, 0x05, 0x36, 0x15, + 0x80, 0x19, 0x12, 0x18, 0xe0, 0x20, 0x12, 0x05, 0x52, 0x0d, 0x00, 0x02, + 0x02, 0x43, 0x9a, 0x80, 0x0c, 0x22, 0x4a, 0x43, 0x15, 0x4b, 0x9b, 0x18, + 0x16, 0x4a, 0x10, 0x78, 0x11, 0x70, 0x98, 0x71, 0x28, 0x00, 0x03, 0x99, + 0xff, 0xf7, 0x48, 0xff, 0x21, 0x00, 0x28, 0x00, 0x02, 0x9a, 0xff, 0xf7, + 0x13, 0xff, 0x05, 0xb0, 0xf0, 0xbd, 0xbd, 0x22, 0x12, 0x02, 0xe8, 0xe7, + 0x0a, 0x4c, 0xbb, 0xe7, 0x0e, 0x4a, 0x0f, 0x49, 0xd2, 0x1a, 0x08, 0x3a, + 0x50, 0x02, 0x40, 0x0d, 0x01, 0x43, 0x99, 0x80, 0x0c, 0x49, 0x52, 0x08, + 0x0a, 0x43, 0xda, 0x80, 0xe2, 0xe7, 0x1c, 0x00, 0xe4, 0xe7, 0xc0, 0x46, + 0x24, 0x01, 0x00, 0xd0, 0x00, 0xed, 0x00, 0xe0, 0xcd, 0x40, 0x00, 0x10, + 0xd8, 0x04, 0x00, 0x20, 0x00, 0xbd, 0xff, 0xff, 0x28, 0x1c, 0x00, 0x20, + 0xaa, 0xaa, 0x00, 0x00, 0x12, 0x05, 0x00, 0x20, 0x00, 0xf0, 0xff, 0xff, + 0x00, 0xf8, 0xff, 0xff, 0x01, 0x23, 0xf7, 0xb5, 0x03, 0x43, 0x04, 0x00, + 0x01, 0x93, 0xfe, 0xf7, 0x9c, 0xfd, 0xef, 0xf3, 0x10, 0x87, 0x72, 0xb6, + 0x1d, 0x4b, 0x1b, 0x68, 0x00, 0x2b, 0xfb, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, + 0x1b, 0x49, 0x22, 0x00, 0x1b, 0x4b, 0x52, 0x1a, 0x52, 0x41, 0x53, 0x43, + 0x1b, 0x0d, 0x5b, 0xb2, 0x9c, 0x46, 0x19, 0x4b, 0x9a, 0x68, 0x83, 0x00, + 0xd2, 0x58, 0x08, 0x00, 0x15, 0x00, 0x2e, 0x00, 0x01, 0x9d, 0x00, 0x22, + 0xae, 0x42, 0x14, 0xd1, 0x13, 0x4a, 0x14, 0x49, 0x92, 0x68, 0xd1, 0x50, + 0x13, 0x4b, 0x1a, 0x78, 0xa2, 0x71, 0x62, 0x46, 0x1a, 0x70, 0xbf, 0xf3, + 0x5f, 0x8f, 0x00, 0x23, 0x0a, 0x4a, 0x13, 0x60, 0x87, 0xf3, 0x10, 0x88, + 0xf7, 0xbd, 0x01, 0x32, 0x0c, 0x30, 0x04, 0x2a, 0xee, 0xd0, 0x06, 0x23, + 0xc3, 0x56, 0x63, 0x45, 0xf7, 0xd1, 0x0c, 0x23, 0x5a, 0x43, 0xf3, 0x33, + 0x89, 0x18, 0x8b, 0x71, 0x07, 0x4b, 0x8b, 0x80, 0xe2, 0xe7, 0xc0, 0x46, + 0x24, 0x01, 0x00, 0xd0, 0xd8, 0x04, 0x00, 0x20, 0xaa, 0xaa, 0x00, 0x00, + 0x00, 0xed, 0x00, 0xe0, 0xcd, 0x40, 0x00, 0x10, 0x28, 0x1c, 0x00, 0x20, + 0x00, 0xbd, 0xff, 0xff, 0x05, 0x4b, 0x06, 0x4a, 0x13, 0x60, 0x06, 0x4a, + 0x13, 0x60, 0x53, 0x60, 0x93, 0x60, 0xd3, 0x60, 0x13, 0x61, 0x53, 0x61, + 0x93, 0x61, 0x70, 0x47, 0x80, 0x80, 0x80, 0x80, 0x00, 0xe4, 0x00, 0xe0, + 0x04, 0xe4, 0x00, 0xe0, 0xd0, 0x23, 0x07, 0xb5, 0x1b, 0x06, 0x1b, 0x68, + 0x01, 0x00, 0x06, 0x48, 0x00, 0x22, 0xc0, 0x18, 0x05, 0x4b, 0x00, 0x93, + 0x05, 0x23, 0x03, 0xf0, 0xd3, 0xfc, 0x00, 0x28, 0x01, 0xdb, 0x1f, 0x23, + 0x18, 0x1a, 0x0e, 0xbd, 0x32, 0x1c, 0x00, 0x20, 0xd7, 0xff, 0x00, 0x10, + 0x30, 0xb5, 0x08, 0x4d, 0x01, 0x22, 0x6c, 0x6a, 0x00, 0x23, 0xa1, 0x42, + 0x06, 0xd8, 0xad, 0x6a, 0x13, 0x00, 0x85, 0x42, 0x02, 0xd2, 0x0b, 0x1b, + 0x59, 0x1e, 0x8b, 0x41, 0x13, 0x40, 0x18, 0x00, 0x30, 0xbd, 0xc0, 0x46, + 0x00, 0x40, 0x05, 0x40, 0x83, 0x68, 0x0a, 0x48, 0x10, 0xb5, 0x09, 0x18, + 0x12, 0x18, 0x12, 0x01, 0x09, 0x01, 0x59, 0x18, 0x9b, 0x18, 0x5c, 0x68, + 0x4a, 0x68, 0x01, 0x20, 0x94, 0x42, 0x05, 0xd8, 0x03, 0xd1, 0x1a, 0x68, + 0x0b, 0x68, 0x9a, 0x42, 0x00, 0xd8, 0x00, 0x20, 0xc0, 0xb2, 0x10, 0xbd, + 0xff, 0xff, 0xff, 0x0f, 0x70, 0xb5, 0x0c, 0x00, 0x05, 0x00, 0x08, 0x00, + 0x00, 0xf0, 0xfc, 0xfa, 0x20, 0x00, 0x00, 0xf0, 0xc5, 0xfb, 0x20, 0x00, + 0x06, 0x49, 0x00, 0xf0, 0x19, 0xfb, 0xff, 0xf7, 0x17, 0xfe, 0x05, 0x4b, + 0x2c, 0x75, 0xc0, 0x18, 0x04, 0x4b, 0x80, 0x00, 0xa4, 0x00, 0x68, 0x60, + 0xe5, 0x50, 0x70, 0xbd, 0xc9, 0x58, 0x00, 0x10, 0x40, 0x00, 0x00, 0x34, + 0x6c, 0x18, 0x00, 0x20, 0x0a, 0x4b, 0x18, 0x68, 0xef, 0xf3, 0x10, 0x82, + 0x72, 0xb6, 0x01, 0x68, 0x00, 0x29, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, + 0x1b, 0x68, 0xbf, 0xf3, 0x5f, 0x8f, 0x00, 0x21, 0x19, 0x60, 0x82, 0xf3, + 0x10, 0x88, 0x40, 0xbf, 0x00, 0x20, 0x00, 0x21, 0x70, 0x47, 0xc0, 0x46, + 0x80, 0x1a, 0x00, 0x20, 0x03, 0x23, 0x30, 0xb5, 0x1c, 0x00, 0x53, 0x43, + 0x4c, 0x43, 0x03, 0x3b, 0xc3, 0x18, 0x03, 0x3c, 0x99, 0x70, 0x01, 0x5d, + 0x05, 0x19, 0x00, 0x29, 0x01, 0xd1, 0x2a, 0x70, 0x30, 0xbd, 0x59, 0x70, + 0xfb, 0xe7, 0x00, 0x00, 0xf0, 0xb5, 0x85, 0xb0, 0x02, 0x93, 0x0c, 0xab, + 0x1c, 0x78, 0x0d, 0xab, 0x1b, 0x78, 0x07, 0x00, 0x05, 0x68, 0x01, 0x92, + 0x03, 0x93, 0x00, 0x2c, 0x10, 0xd1, 0xac, 0x7b, 0x00, 0x2c, 0x47, 0xd0, + 0x03, 0x23, 0x63, 0x43, 0x2a, 0x68, 0x03, 0x3b, 0xd3, 0x18, 0x5a, 0x78, + 0xaa, 0x73, 0x00, 0x2a, 0x00, 0xd1, 0xea, 0x73, 0x00, 0x22, 0x9a, 0x70, + 0x5a, 0x70, 0x1a, 0x70, 0x21, 0x4b, 0xba, 0x68, 0xe3, 0x18, 0x1b, 0x01, + 0xd3, 0x18, 0x01, 0x9a, 0x1a, 0x60, 0x02, 0x9a, 0x5a, 0x60, 0x0a, 0x9a, + 0x9a, 0x60, 0x0b, 0x9a, 0xda, 0x60, 0x03, 0x23, 0x63, 0x43, 0x2a, 0x68, + 0x03, 0x3b, 0xd3, 0x18, 0x00, 0x22, 0x9a, 0x70, 0x5a, 0x70, 0x1a, 0x70, + 0x6e, 0x7b, 0x96, 0x42, 0x28, 0xd0, 0x22, 0x00, 0x31, 0x00, 0xa8, 0x68, + 0x6b, 0x68, 0x98, 0x47, 0x00, 0x28, 0x1c, 0xd0, 0x22, 0x00, 0x31, 0x00, + 0x28, 0x68, 0xff, 0xf7, 0xab, 0xff, 0x6e, 0x73, 0xa6, 0x42, 0x11, 0xd1, + 0x38, 0x7d, 0x01, 0x9a, 0x02, 0x9b, 0x00, 0xf0, 0xdd, 0xfa, 0x05, 0x1e, + 0x06, 0xd0, 0x03, 0x9b, 0x00, 0x2b, 0x03, 0xd1, 0x21, 0x00, 0x38, 0x68, + 0x00, 0xf0, 0xf2, 0xfb, 0x0e, 0x9b, 0x00, 0x2b, 0x00, 0xd0, 0x1d, 0x70, + 0x20, 0x00, 0x05, 0xb0, 0xf0, 0xbd, 0x32, 0x00, 0x21, 0x00, 0x28, 0x68, + 0xff, 0xf7, 0x8e, 0xff, 0x26, 0x00, 0xe0, 0xe7, 0xff, 0xff, 0xff, 0x0f, + 0x00, 0x23, 0xf0, 0xb5, 0x8f, 0xb0, 0x0b, 0x93, 0x5d, 0x4b, 0x82, 0x00, + 0xd4, 0x58, 0x0c, 0x90, 0x00, 0xf0, 0x58, 0xfa, 0x02, 0x00, 0x0b, 0x00, + 0x60, 0x68, 0xef, 0xf3, 0x10, 0x81, 0x08, 0x91, 0x72, 0xb6, 0x01, 0x68, + 0x00, 0x29, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x21, 0x68, 0x8c, 0x46, + 0x49, 0x7b, 0x07, 0x91, 0x00, 0x29, 0x74, 0xd0, 0x52, 0x48, 0x0d, 0x18, + 0xa1, 0x68, 0x2d, 0x01, 0x4d, 0x19, 0x2e, 0x68, 0x6f, 0x68, 0x30, 0x00, + 0x39, 0x00, 0x80, 0x1a, 0x99, 0x41, 0x00, 0x29, 0x5d, 0xdc, 0x01, 0xd1, + 0x00, 0x28, 0x5a, 0xd1, 0x00, 0x21, 0x60, 0x46, 0x00, 0xf0, 0xa8, 0xfb, + 0x2e, 0x68, 0x6f, 0x68, 0xab, 0x68, 0x07, 0x9a, 0x0a, 0x93, 0xe3, 0x68, + 0xed, 0x68, 0x9b, 0x18, 0x01, 0x3b, 0x1b, 0x78, 0x0b, 0x93, 0x1b, 0x02, + 0x03, 0x43, 0x00, 0x20, 0x23, 0x61, 0x63, 0x68, 0xbf, 0xf3, 0x5f, 0x8f, + 0x00, 0x22, 0x1a, 0x60, 0x08, 0x9b, 0x83, 0xf3, 0x10, 0x88, 0x0a, 0x9b, + 0x93, 0x42, 0x6f, 0xd0, 0x0b, 0x9b, 0x29, 0x00, 0x18, 0x02, 0x07, 0x9b, + 0x18, 0x43, 0x0a, 0x9b, 0x98, 0x47, 0x08, 0x90, 0x09, 0x91, 0x62, 0x68, + 0xef, 0xf3, 0x10, 0x83, 0x0d, 0x93, 0x72, 0xb6, 0x13, 0x68, 0x00, 0x2b, + 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x09, 0x9b, 0x00, 0x2b, 0x36, 0xda, + 0x23, 0x69, 0x00, 0x2b, 0x43, 0xd0, 0x08, 0x98, 0x09, 0x99, 0x32, 0x00, + 0x3b, 0x00, 0x12, 0x1a, 0x8b, 0x41, 0x9f, 0x42, 0x02, 0xd8, 0x04, 0xd1, + 0x96, 0x42, 0x02, 0xd9, 0x01, 0x22, 0x52, 0x42, 0x13, 0x00, 0x00, 0x21, + 0x04, 0x91, 0x01, 0x31, 0x03, 0x91, 0x07, 0x99, 0x20, 0x00, 0x02, 0x91, + 0x0a, 0x99, 0x01, 0x95, 0x00, 0x91, 0xff, 0xf7, 0x1f, 0xff, 0x00, 0x22, + 0x63, 0x68, 0x22, 0x61, 0xbf, 0xf3, 0x5f, 0x8f, 0x1a, 0x60, 0x0d, 0x9b, + 0x83, 0xf3, 0x10, 0x88, 0x80, 0xe7, 0x00, 0x25, 0x32, 0x00, 0x3b, 0x00, + 0x0c, 0x98, 0x00, 0xf0, 0x37, 0xfa, 0x00, 0x26, 0x00, 0x27, 0x0a, 0x95, + 0xad, 0xe7, 0x07, 0x9d, 0x00, 0x26, 0x00, 0x27, 0x28, 0x00, 0x0a, 0x95, + 0xa7, 0xe7, 0x08, 0x9b, 0x09, 0x9a, 0x13, 0x43, 0x0b, 0xd0, 0x23, 0x69, + 0x00, 0x2b, 0x08, 0xd0, 0x00, 0xf0, 0xc2, 0xf9, 0x08, 0x9a, 0x09, 0x9b, + 0x06, 0x00, 0x0f, 0x00, 0x92, 0x19, 0x7b, 0x41, 0xc1, 0xe7, 0x22, 0x68, + 0xd1, 0x7b, 0x00, 0x29, 0x06, 0xd0, 0x03, 0x23, 0x4b, 0x43, 0x11, 0x68, + 0xcb, 0x18, 0x07, 0x99, 0x03, 0x3b, 0x59, 0x70, 0x07, 0x9b, 0xd3, 0x73, + 0xe1, 0x68, 0x01, 0x3b, 0xca, 0x5c, 0x01, 0x32, 0xca, 0x54, 0xc2, 0xe7, + 0x00, 0x28, 0x00, 0xd0, 0x4a, 0xe7, 0x0f, 0xb0, 0xf0, 0xbd, 0xc0, 0x46, + 0x6c, 0x18, 0x00, 0x20, 0xff, 0xff, 0xff, 0x0f, 0x10, 0xb5, 0x09, 0x4c, + 0x63, 0x68, 0x00, 0x2b, 0x09, 0xd1, 0x10, 0x21, 0x20, 0x68, 0x23, 0x00, + 0x06, 0x4a, 0x00, 0xf0, 0xb9, 0xfa, 0x03, 0x21, 0x20, 0x00, 0xff, 0xf7, + 0x81, 0xfe, 0x0a, 0x21, 0x03, 0x48, 0x03, 0xf0, 0x37, 0xfc, 0x10, 0xbd, + 0x20, 0x05, 0x00, 0x20, 0x41, 0x57, 0x00, 0x10, 0x80, 0x1a, 0x00, 0x20, + 0x00, 0x48, 0x70, 0x47, 0x20, 0x05, 0x00, 0x20, 0xf0, 0xb5, 0x8d, 0xb0, + 0x07, 0x93, 0x14, 0xab, 0x1b, 0x78, 0x00, 0x27, 0x09, 0x93, 0x1f, 0x23, + 0x06, 0x00, 0x06, 0x92, 0x04, 0xaa, 0x9b, 0x18, 0x1f, 0x70, 0x72, 0x68, + 0xef, 0xf3, 0x10, 0x85, 0x72, 0xb6, 0x13, 0x68, 0x00, 0x2b, 0xfc, 0xd0, + 0xbf, 0xf3, 0x5f, 0x8f, 0x1f, 0x24, 0x04, 0xab, 0xe4, 0x18, 0x13, 0x9b, + 0x30, 0x00, 0x01, 0x93, 0x12, 0x9b, 0x04, 0x94, 0x00, 0x93, 0x03, 0x97, + 0x06, 0x9a, 0x07, 0x9b, 0x02, 0x97, 0xff, 0xf7, 0x95, 0xfe, 0x02, 0x00, + 0x00, 0x20, 0x82, 0x42, 0x03, 0xd0, 0xf3, 0x68, 0x9b, 0x18, 0x01, 0x3b, + 0x18, 0x78, 0x71, 0x68, 0xbf, 0xf3, 0x5f, 0x8f, 0x0f, 0x60, 0x85, 0xf3, + 0x10, 0x88, 0x00, 0x2a, 0x28, 0xd0, 0x21, 0x78, 0x00, 0x29, 0x28, 0xd1, + 0x00, 0x02, 0x10, 0x43, 0x0d, 0xb0, 0xf0, 0xbd, 0x04, 0x00, 0x0d, 0x1e, + 0x12, 0xda, 0x06, 0x9a, 0x07, 0x9b, 0x12, 0x1b, 0xab, 0x41, 0x1d, 0x00, + 0x07, 0x9b, 0x14, 0x00, 0xab, 0x42, 0x03, 0xd8, 0x05, 0xd1, 0x06, 0x9b, + 0xa3, 0x42, 0x02, 0xd9, 0x01, 0x24, 0x64, 0x42, 0x25, 0x00, 0x06, 0x94, + 0x07, 0x95, 0xba, 0xe7, 0x00, 0xf0, 0x2c, 0xf9, 0x02, 0x00, 0x0b, 0x00, + 0xa4, 0x18, 0x5d, 0x41, 0xa9, 0x42, 0xf1, 0xd8, 0xf3, 0xd1, 0xa0, 0x42, + 0xf1, 0xd9, 0xed, 0xe7, 0x01, 0x20, 0x40, 0x42, 0xd8, 0xe7, 0x09, 0x9b, + 0x00, 0x2b, 0x06, 0xd0, 0x12, 0x9b, 0x00, 0x20, 0x13, 0x99, 0x98, 0x47, + 0x03, 0x00, 0x0b, 0x43, 0xd0, 0xd1, 0x00, 0x20, 0xcc, 0xe7, 0xf8, 0xb5, + 0x0b, 0x00, 0x04, 0x00, 0x41, 0x68, 0xef, 0xf3, 0x10, 0x85, 0x72, 0xb6, + 0x0a, 0x68, 0x00, 0x2a, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x27, 0x68, + 0xd9, 0xb2, 0x78, 0x7b, 0xda, 0xb2, 0x88, 0x42, 0x07, 0xd0, 0x03, 0x26, + 0x56, 0x43, 0x38, 0x68, 0x86, 0x19, 0x03, 0x3e, 0xb0, 0x78, 0x00, 0x28, + 0x13, 0xd0, 0xe0, 0x68, 0x1b, 0x0a, 0x82, 0x18, 0x01, 0x3a, 0x12, 0x78, + 0xdb, 0xb2, 0x00, 0x20, 0x9a, 0x42, 0x02, 0xd1, 0x38, 0x00, 0x00, 0xf0, + 0x6d, 0xfa, 0x63, 0x68, 0xbf, 0xf3, 0x5f, 0x8f, 0x00, 0x22, 0x1a, 0x60, + 0x85, 0xf3, 0x10, 0x88, 0xf8, 0xbd, 0x22, 0x69, 0x9a, 0x42, 0xf4, 0xd1, + 0x20, 0x61, 0xf2, 0xe7, 0xf0, 0xb5, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x24, + 0x64, 0x42, 0xe5, 0x17, 0xa4, 0x19, 0x7d, 0x41, 0x85, 0xb0, 0x8d, 0x42, + 0x02, 0xd8, 0x03, 0xd1, 0x84, 0x42, 0x01, 0xd9, 0x00, 0x24, 0x00, 0x25, + 0x00, 0xf0, 0xce, 0xf8, 0x22, 0x00, 0x2b, 0x00, 0x12, 0x1a, 0x8b, 0x41, + 0x00, 0x2b, 0x08, 0xdc, 0x01, 0xd1, 0x00, 0x2a, 0x05, 0xd1, 0x30, 0x00, + 0x39, 0x00, 0x00, 0xf0, 0xcb, 0xf8, 0x05, 0xb0, 0xf0, 0xbd, 0x00, 0x23, + 0x02, 0x93, 0x01, 0x93, 0x10, 0x4b, 0x22, 0x00, 0x00, 0x93, 0x10, 0x48, + 0x2b, 0x00, 0xff, 0xf7, 0x35, 0xff, 0x00, 0x28, 0xed, 0xdb, 0x20, 0x00, + 0x29, 0x00, 0xff, 0xf7, 0x75, 0xfd, 0x00, 0x28, 0xe7, 0xd1, 0x0b, 0x4b, + 0x18, 0x68, 0xef, 0xf3, 0x10, 0x82, 0x72, 0xb6, 0x01, 0x68, 0x00, 0x29, + 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x1b, 0x68, 0xbf, 0xf3, 0x5f, 0x8f, + 0x00, 0x21, 0x19, 0x60, 0x82, 0xf3, 0x10, 0x88, 0x20, 0xbf, 0xe6, 0xe7, + 0xad, 0x57, 0x00, 0x10, 0x20, 0x05, 0x00, 0x20, 0x80, 0x1a, 0x00, 0x20, + 0x70, 0xb5, 0x04, 0x00, 0x0d, 0x00, 0x00, 0xf0, 0x8f, 0xf8, 0x02, 0x00, + 0x0b, 0x00, 0x20, 0x00, 0x29, 0x00, 0x80, 0x18, 0x59, 0x41, 0x8b, 0x42, + 0x02, 0xd8, 0x04, 0xd1, 0x82, 0x42, 0x02, 0xd9, 0x01, 0x20, 0x40, 0x42, + 0xc1, 0x17, 0xff, 0xf7, 0x9f, 0xff, 0x70, 0xbd, 0xfa, 0x22, 0x10, 0xb5, + 0x00, 0x23, 0x92, 0x00, 0x00, 0x21, 0x01, 0xf0, 0x07, 0xfc, 0xff, 0xf7, + 0xe1, 0xff, 0x10, 0xbd, 0x7f, 0xb5, 0x00, 0x23, 0x0c, 0x4e, 0x02, 0x93, + 0x01, 0x93, 0x0c, 0x4b, 0x02, 0x00, 0x00, 0x93, 0x05, 0x00, 0x0b, 0x00, + 0x30, 0x00, 0x0c, 0x00, 0xff, 0xf7, 0xe6, 0xfe, 0x01, 0x1e, 0x05, 0xdc, + 0x28, 0x00, 0x21, 0x00, 0xff, 0xf7, 0x26, 0xfd, 0x04, 0xb0, 0x70, 0xbd, + 0x20, 0xbf, 0x30, 0x00, 0xff, 0xf7, 0x47, 0xff, 0xf4, 0xe7, 0xc0, 0x46, + 0x20, 0x05, 0x00, 0x20, 0xad, 0x57, 0x00, 0x10, 0xf7, 0xb5, 0xef, 0xf3, + 0x05, 0x82, 0x3f, 0x23, 0x1a, 0x40, 0x10, 0x00, 0x01, 0x92, 0x10, 0x38, + 0xef, 0xf3, 0x10, 0x87, 0x72, 0xb6, 0x18, 0x4b, 0x1b, 0x68, 0x00, 0x2b, + 0xfb, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x01, 0x26, 0x34, 0x00, 0x84, 0x40, + 0x14, 0x4d, 0x15, 0x4b, 0x6c, 0x63, 0x1b, 0x78, 0x1a, 0x00, 0xc2, 0x40, + 0x94, 0x46, 0x61, 0x46, 0x00, 0x22, 0x31, 0x42, 0x0a, 0xd0, 0x11, 0x4e, + 0x69, 0x6a, 0x85, 0x00, 0xae, 0x59, 0xb1, 0x42, 0x0f, 0xd3, 0x0f, 0x4a, + 0x0c, 0x49, 0xa3, 0x43, 0xaa, 0x58, 0x0b, 0x70, 0xbf, 0xf3, 0x5f, 0x8f, + 0x00, 0x23, 0x07, 0x49, 0x0b, 0x60, 0x87, 0xf3, 0x10, 0x88, 0x9a, 0x42, + 0x00, 0xd0, 0x90, 0x47, 0xf7, 0xbd, 0x01, 0x9b, 0x07, 0x49, 0x9b, 0x00, + 0x5b, 0x18, 0x1c, 0x68, 0x1c, 0x60, 0xed, 0xe7, 0x28, 0x01, 0x00, 0xd0, + 0x00, 0x40, 0x05, 0x40, 0x31, 0x1c, 0x00, 0x20, 0x84, 0x1a, 0x00, 0x20, + 0x24, 0x13, 0x00, 0x20, 0xd0, 0x3f, 0x05, 0x40, 0x10, 0xb5, 0x01, 0x00, + 0x02, 0x4a, 0x03, 0x48, 0x03, 0xf0, 0x79, 0xf9, 0x10, 0xbd, 0xc0, 0x46, + 0xf2, 0xff, 0x00, 0x10, 0xe6, 0x1b, 0x00, 0x20, 0x03, 0x4b, 0x59, 0x6a, + 0x0a, 0x00, 0x98, 0x6a, 0x59, 0x6a, 0x8a, 0x42, 0xfa, 0xd1, 0x70, 0x47, + 0x00, 0x40, 0x05, 0x40, 0x05, 0x4b, 0x5a, 0x6a, 0x8a, 0x42, 0xfc, 0xd3, + 0x8a, 0x42, 0x02, 0xd1, 0x9a, 0x6a, 0x82, 0x42, 0x00, 0xd3, 0x70, 0x47, + 0x5a, 0x6a, 0xf7, 0xe7, 0x00, 0x40, 0x05, 0x40, 0xf7, 0xb5, 0x04, 0x00, + 0x0d, 0x00, 0xef, 0xf3, 0x10, 0x83, 0x00, 0x93, 0x72, 0xb6, 0x1c, 0x4f, + 0x3b, 0x68, 0x00, 0x2b, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0xa3, 0x00, + 0x19, 0x4e, 0x01, 0x93, 0x00, 0x2d, 0x1b, 0xd0, 0x20, 0x00, 0xff, 0xf7, + 0x45, 0xfb, 0x86, 0x42, 0x0b, 0xd0, 0x31, 0x00, 0x20, 0x00, 0xff, 0xf7, + 0x47, 0xfb, 0x01, 0x21, 0x20, 0x00, 0xff, 0xf7, 0x2b, 0xfb, 0x01, 0x23, + 0xa3, 0x40, 0x11, 0x4a, 0x13, 0x60, 0x11, 0x4b, 0x01, 0x9a, 0x9d, 0x50, + 0xbf, 0xf3, 0x5f, 0x8f, 0x00, 0x23, 0x3b, 0x60, 0x00, 0x9b, 0x83, 0xf3, + 0x10, 0x88, 0xf7, 0xbd, 0x0b, 0x4b, 0xa2, 0x00, 0x9d, 0x50, 0x01, 0x22, + 0xa2, 0x40, 0x0a, 0x49, 0x20, 0x00, 0x0b, 0x78, 0x93, 0x43, 0x0b, 0x70, + 0x31, 0x00, 0xff, 0xf7, 0x47, 0xfb, 0x29, 0x00, 0x20, 0x00, 0xff, 0xf7, + 0x0b, 0xfb, 0xe5, 0xe7, 0x28, 0x01, 0x00, 0xd0, 0xe5, 0x5c, 0x00, 0x10, + 0x38, 0x60, 0x05, 0x40, 0x24, 0x13, 0x00, 0x20, 0x31, 0x1c, 0x00, 0x20, + 0xf0, 0xb5, 0x85, 0xb0, 0x1e, 0x00, 0x04, 0x00, 0x01, 0x92, 0xff, 0xf7, + 0x97, 0xff, 0x8e, 0x42, 0x03, 0xd8, 0x47, 0xd1, 0x01, 0x9b, 0x83, 0x42, + 0x44, 0xd9, 0xef, 0xf3, 0x10, 0x83, 0x03, 0x93, 0x72, 0xb6, 0x21, 0x4b, + 0x1b, 0x68, 0x00, 0x2b, 0xfb, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x01, 0x25, + 0xa5, 0x40, 0x1e, 0x4b, 0x1e, 0x4f, 0x1b, 0x78, 0x00, 0x93, 0x2b, 0x43, + 0xdb, 0xb2, 0x02, 0x93, 0x02, 0x9a, 0x1a, 0x4b, 0x1a, 0x70, 0x01, 0x9a, + 0x23, 0x1d, 0x9b, 0x00, 0x7d, 0x63, 0xda, 0x51, 0x18, 0x4a, 0xa3, 0x00, + 0x9e, 0x50, 0x3b, 0x6a, 0x2b, 0x42, 0x0a, 0xd1, 0x00, 0x20, 0xbf, 0xf3, + 0x5f, 0x8f, 0x00, 0x23, 0x10, 0x4a, 0x13, 0x60, 0x03, 0x9b, 0x83, 0xf3, + 0x10, 0x88, 0x05, 0xb0, 0xf0, 0xbd, 0xff, 0xf7, 0x63, 0xff, 0x8e, 0x42, + 0xf0, 0xd8, 0x02, 0xd1, 0x01, 0x9b, 0x83, 0x42, 0xec, 0xd8, 0x02, 0x9b, + 0x00, 0x9a, 0x01, 0x20, 0x93, 0x42, 0xe8, 0xd0, 0x1f, 0x23, 0x02, 0x00, + 0x1c, 0x40, 0xa2, 0x40, 0x08, 0x4b, 0x3d, 0x62, 0x7d, 0x63, 0x1a, 0x60, + 0x03, 0x4b, 0x00, 0x9a, 0x1a, 0x70, 0xdc, 0xe7, 0x01, 0x20, 0xe2, 0xe7, + 0x28, 0x01, 0x00, 0xd0, 0x31, 0x1c, 0x00, 0x20, 0x00, 0x40, 0x05, 0x40, + 0x84, 0x1a, 0x00, 0x20, 0x80, 0xe2, 0x00, 0xe0, 0x10, 0xb5, 0xef, 0xf3, + 0x10, 0x84, 0x72, 0xb6, 0x0a, 0x49, 0x0b, 0x68, 0x00, 0x2b, 0xfc, 0xd0, + 0xbf, 0xf3, 0x5f, 0x8f, 0x01, 0x23, 0x83, 0x40, 0x07, 0x4a, 0x08, 0x48, + 0x13, 0x62, 0x02, 0x78, 0x9a, 0x43, 0x02, 0x70, 0xbf, 0xf3, 0x5f, 0x8f, + 0x00, 0x23, 0x0b, 0x60, 0x84, 0xf3, 0x10, 0x88, 0x10, 0xbd, 0xc0, 0x46, + 0x28, 0x01, 0x00, 0xd0, 0x00, 0x40, 0x05, 0x40, 0x31, 0x1c, 0x00, 0x20, + 0x03, 0x23, 0x30, 0xb5, 0x1c, 0x00, 0x53, 0x43, 0x4c, 0x43, 0x03, 0x3b, + 0xc3, 0x18, 0x03, 0x3c, 0x99, 0x70, 0x01, 0x5d, 0x05, 0x19, 0x00, 0x29, + 0x01, 0xd1, 0x2a, 0x70, 0x30, 0xbd, 0x59, 0x70, 0xfb, 0xe7, 0x70, 0xb5, + 0x06, 0x00, 0x0c, 0x00, 0x15, 0x00, 0x00, 0x29, 0x12, 0xd0, 0x00, 0x2a, + 0x09, 0xd0, 0x80, 0x68, 0x73, 0x68, 0x98, 0x47, 0x00, 0x28, 0x06, 0xd0, + 0x2a, 0x00, 0x21, 0x00, 0x30, 0x68, 0xff, 0xf7, 0xdd, 0xff, 0x20, 0x00, + 0x70, 0xbd, 0x22, 0x00, 0x29, 0x00, 0x30, 0x68, 0xff, 0xf7, 0xd6, 0xff, + 0x2c, 0x00, 0xf6, 0xe7, 0x01, 0x22, 0x00, 0x23, 0x30, 0xb5, 0x04, 0x7b, + 0x82, 0x73, 0x43, 0x73, 0x02, 0x68, 0xc4, 0x73, 0x03, 0x20, 0x01, 0x33, + 0xdd, 0xb2, 0xac, 0x42, 0x05, 0xd8, 0x00, 0x23, 0x60, 0x43, 0x12, 0x18, + 0x03, 0x3a, 0x53, 0x70, 0x30, 0xbd, 0x01, 0x00, 0x59, 0x43, 0x51, 0x18, + 0x03, 0x39, 0x01, 0x35, 0x4d, 0x70, 0xee, 0xe7, 0x10, 0xb5, 0x01, 0x73, + 0x42, 0x60, 0x83, 0x60, 0xff, 0xf7, 0xe0, 0xff, 0x10, 0xbd, 0x70, 0xb5, + 0x04, 0x00, 0x00, 0x29, 0x1d, 0xd0, 0x05, 0x68, 0x03, 0x20, 0x03, 0x00, + 0x4b, 0x43, 0x03, 0x3b, 0xeb, 0x18, 0x5a, 0x78, 0x00, 0x2a, 0x14, 0xd0, + 0x00, 0x26, 0x50, 0x43, 0x03, 0x38, 0x28, 0x18, 0x45, 0x78, 0x46, 0x70, + 0x5e, 0x70, 0x20, 0x00, 0xff, 0xf7, 0xad, 0xff, 0x29, 0x00, 0x06, 0x00, + 0x20, 0x00, 0xff, 0xf7, 0xe4, 0xff, 0x31, 0x00, 0x02, 0x00, 0x20, 0x00, + 0xff, 0xf7, 0xa3, 0xff, 0x01, 0x00, 0x08, 0x00, 0x70, 0xbd, 0xf7, 0xb5, + 0x03, 0x27, 0x3e, 0x00, 0x4e, 0x43, 0x03, 0x68, 0x03, 0x3e, 0x0d, 0x00, + 0x99, 0x5d, 0x04, 0x00, 0x01, 0x92, 0xff, 0xf7, 0xd0, 0xff, 0x01, 0x9b, + 0x00, 0x2b, 0x08, 0xd0, 0xe3, 0x7b, 0x00, 0x2b, 0x04, 0xd0, 0x5f, 0x43, + 0x23, 0x68, 0xdf, 0x19, 0x03, 0x3f, 0x7d, 0x70, 0xe5, 0x73, 0x22, 0x68, + 0x00, 0x28, 0x05, 0xd0, 0x03, 0x23, 0x00, 0x21, 0x43, 0x43, 0xd3, 0x18, + 0x03, 0x3b, 0x99, 0x70, 0x00, 0x23, 0x92, 0x19, 0x53, 0x70, 0xfe, 0xbd, + 0x70, 0xb5, 0x45, 0x7b, 0x0a, 0x00, 0x29, 0x00, 0x04, 0x00, 0xff, 0xf7, + 0xd4, 0xff, 0x60, 0x73, 0x28, 0x00, 0x70, 0xbd, 0x70, 0xb5, 0x04, 0x00, + 0x08, 0x1e, 0x07, 0xd0, 0x63, 0x7b, 0x8b, 0x42, 0x05, 0xd1, 0x01, 0x21, + 0x20, 0x00, 0xff, 0xf7, 0xeb, 0xff, 0x01, 0x20, 0x70, 0xbd, 0x03, 0x26, + 0x33, 0x00, 0x4b, 0x43, 0x25, 0x68, 0x03, 0x3b, 0xeb, 0x18, 0x9a, 0x78, + 0x10, 0x1e, 0xf5, 0xd0, 0x72, 0x43, 0x03, 0x3a, 0xa8, 0x18, 0xaa, 0x5c, + 0x8a, 0x42, 0x11, 0xd1, 0x5a, 0x78, 0x02, 0x70, 0x00, 0x22, 0x20, 0x00, + 0x9a, 0x70, 0x5a, 0x70, 0x01, 0x32, 0xff, 0xf7, 0xac, 0xff, 0x61, 0x7b, + 0x02, 0x00, 0x20, 0x00, 0xff, 0xf7, 0x47, 0xff, 0x60, 0x73, 0xde, 0xe7, + 0x00, 0x2a, 0xef, 0xd0, 0x72, 0x43, 0x03, 0x3a, 0xa8, 0x18, 0x42, 0x78, + 0x8a, 0x42, 0xf7, 0xd1, 0x5a, 0x78, 0x42, 0x70, 0xe6, 0xe7, 0x70, 0xb5, + 0x16, 0x00, 0x0d, 0x00, 0x19, 0x00, 0x04, 0x00, 0x03, 0xf0, 0xee, 0xf8, + 0x29, 0x00, 0x70, 0x1c, 0x03, 0xf0, 0x7b, 0xfc, 0x00, 0x23, 0xe6, 0x81, + 0xa5, 0x81, 0x60, 0x60, 0xa3, 0x60, 0x70, 0xbd, 0x10, 0xb5, 0x04, 0x00, + 0xff, 0xf7, 0x4c, 0xf9, 0x01, 0x00, 0x20, 0x00, 0x03, 0xf0, 0xdc, 0xf8, + 0xff, 0x23, 0x23, 0x71, 0xbf, 0xf3, 0x5f, 0x8f, 0x10, 0xbd, 0x10, 0xb5, + 0x04, 0x00, 0xff, 0xf7, 0x3f, 0xf9, 0x01, 0x00, 0x20, 0x00, 0x03, 0xf0, + 0xcf, 0xf8, 0xff, 0x23, 0xa3, 0x80, 0xbf, 0xf3, 0x5f, 0x8f, 0x10, 0xbd, + 0x02, 0x4b, 0x10, 0x30, 0x9b, 0x68, 0x80, 0x00, 0xc0, 0x58, 0x70, 0x47, + 0x00, 0xed, 0x00, 0xe0, 0xf8, 0xb5, 0x04, 0x00, 0x0e, 0x00, 0xef, 0xf3, + 0x10, 0x87, 0x72, 0xb6, 0xff, 0xf7, 0xf0, 0xff, 0x05, 0x00, 0xb0, 0x42, + 0x07, 0xd0, 0x09, 0x4b, 0x98, 0x42, 0x02, 0xd3, 0x08, 0x4b, 0x98, 0x42, + 0x01, 0xd3, 0x00, 0xf0, 0x8f, 0xfa, 0x07, 0x4b, 0x10, 0x34, 0x9b, 0x68, + 0xa4, 0x00, 0xe6, 0x50, 0xbf, 0xf3, 0x5f, 0x8f, 0x87, 0xf3, 0x10, 0x88, + 0x28, 0x00, 0xf8, 0xbd, 0xc0, 0x40, 0x00, 0x10, 0xcc, 0x40, 0x00, 0x10, + 0x00, 0xed, 0x00, 0xe0, 0x14, 0x23, 0x10, 0xb5, 0x01, 0x00, 0x18, 0x88, + 0x04, 0x33, 0x1b, 0x88, 0x98, 0x47, 0x10, 0xbd, 0x16, 0x23, 0x10, 0xb5, + 0x01, 0x00, 0x18, 0x88, 0x02, 0x33, 0x1b, 0x88, 0x98, 0x47, 0x10, 0xbd, + 0xf8, 0xb5, 0x0e, 0x00, 0x04, 0x00, 0x00, 0x27, 0x01, 0x25, 0xb7, 0x42, + 0x01, 0xd1, 0x28, 0x00, 0xf8, 0xbd, 0x20, 0x68, 0xff, 0xf7, 0xe4, 0xff, + 0x01, 0xc4, 0x43, 0x1e, 0x98, 0x41, 0x40, 0x42, 0x05, 0x40, 0x01, 0x37, + 0xf1, 0xe7, 0x00, 0x00, 0x0f, 0x4b, 0x10, 0xb5, 0xc0, 0x18, 0x43, 0x42, + 0x58, 0x41, 0x83, 0x00, 0x0d, 0x48, 0x1c, 0x58, 0x01, 0x23, 0x20, 0x20, + 0x8b, 0x40, 0x40, 0x1a, 0x01, 0x3b, 0x00, 0x2a, 0x0d, 0xdb, 0x82, 0x42, + 0x03, 0xdc, 0x93, 0x40, 0x10, 0x00, 0x1c, 0x42, 0x01, 0xd0, 0x01, 0x20, + 0x40, 0x42, 0x10, 0xbd, 0x1a, 0x00, 0x82, 0x40, 0x14, 0x42, 0xfa, 0xd0, + 0x01, 0x38, 0x00, 0x28, 0xf8, 0xda, 0xf4, 0xe7, 0x00, 0x00, 0xd0, 0xaf, + 0x1c, 0x13, 0x00, 0x20, 0x05, 0x23, 0xf7, 0xb5, 0xcb, 0x56, 0x00, 0x2b, + 0x01, 0xdb, 0x9a, 0x42, 0x12, 0xd1, 0x0b, 0x79, 0x9c, 0x46, 0x18, 0x4b, + 0x65, 0x46, 0xc3, 0x18, 0x5c, 0x42, 0x5c, 0x41, 0x16, 0x4b, 0x01, 0x94, + 0xa4, 0x00, 0xe4, 0x58, 0x01, 0x23, 0xab, 0x40, 0x01, 0x3b, 0x93, 0x40, + 0x1d, 0x00, 0x25, 0x40, 0x23, 0x42, 0x16, 0xd0, 0x11, 0x48, 0x00, 0xf0, + 0x03, 0xfa, 0x4e, 0x78, 0x0f, 0x78, 0x36, 0x02, 0x3e, 0x43, 0x8f, 0x78, + 0x3f, 0x04, 0x37, 0x43, 0xce, 0x78, 0x36, 0x06, 0x3e, 0x43, 0x6f, 0x00, + 0xbf, 0x5b, 0x7e, 0x0b, 0x00, 0xd1, 0xbf, 0x18, 0x56, 0x19, 0x12, 0x36, + 0xb6, 0x00, 0x37, 0x50, 0x01, 0x35, 0x65, 0x45, 0xe9, 0xd3, 0x01, 0x9a, + 0x03, 0x49, 0x92, 0x00, 0x23, 0x43, 0x53, 0x50, 0xf7, 0xbd, 0xc0, 0x46, + 0x00, 0x00, 0xd0, 0xaf, 0x1c, 0x13, 0x00, 0x20, 0x14, 0x00, 0x01, 0x10, + 0x09, 0x4b, 0x13, 0xb5, 0xc0, 0x18, 0x43, 0x42, 0x58, 0x41, 0x08, 0x4a, + 0x84, 0x00, 0x00, 0x92, 0x07, 0x48, 0x22, 0x00, 0xe3, 0x1c, 0x02, 0xf0, + 0xed, 0xfe, 0x84, 0x42, 0x01, 0xdc, 0x00, 0x1b, 0x16, 0xbd, 0x01, 0x20, + 0x40, 0x42, 0xfb, 0xe7, 0x00, 0x00, 0xd0, 0xaf, 0x25, 0x00, 0x01, 0x10, + 0xe7, 0x1b, 0x00, 0x20, 0x70, 0xb5, 0x06, 0x00, 0x0c, 0x00, 0x02, 0xf0, + 0x9d, 0xfe, 0x05, 0x22, 0x05, 0x00, 0xa2, 0x56, 0x21, 0x79, 0x30, 0x00, + 0xff, 0xf7, 0x76, 0xff, 0x04, 0x00, 0x01, 0x34, 0x63, 0x1e, 0x9c, 0x41, + 0x28, 0x00, 0x02, 0xf0, 0x9b, 0xfe, 0xe0, 0xb2, 0x70, 0xbd, 0x00, 0x00, + 0xf8, 0xb5, 0x0d, 0x00, 0x06, 0x00, 0x02, 0xf0, 0x87, 0xfe, 0x05, 0x22, + 0x07, 0x00, 0xaa, 0x56, 0x30, 0x00, 0x29, 0x79, 0xff, 0xf7, 0x60, 0xff, + 0x04, 0x1e, 0x02, 0xda, 0x06, 0x48, 0x00, 0xf0, 0x9f, 0xf9, 0x02, 0x00, + 0x29, 0x00, 0x30, 0x00, 0xff, 0xf7, 0x7a, 0xff, 0x38, 0x00, 0x02, 0xf0, + 0x7f, 0xfe, 0x20, 0x00, 0xf8, 0xbd, 0xc0, 0x46, 0x14, 0x00, 0x01, 0x10, + 0xf0, 0xb5, 0x01, 0x25, 0x8d, 0x40, 0x04, 0x68, 0xac, 0x43, 0x04, 0x60, + 0x18, 0x24, 0x4c, 0x43, 0x04, 0x19, 0x25, 0x00, 0xc8, 0x35, 0x00, 0x2b, + 0x2a, 0xd0, 0x1e, 0x68, 0x2e, 0x60, 0x5e, 0x68, 0x6e, 0x60, 0x9e, 0x68, + 0xdb, 0x68, 0xae, 0x60, 0xdc, 0x34, 0x23, 0x60, 0x18, 0x24, 0x4c, 0x43, + 0x25, 0x00, 0x80, 0x23, 0xd0, 0x35, 0x45, 0x19, 0x5b, 0x01, 0x2b, 0x43, + 0x80, 0x25, 0x2d, 0x06, 0x1d, 0x60, 0x1d, 0x60, 0x0f, 0x4b, 0x0d, 0x1d, + 0x8b, 0x40, 0x83, 0x60, 0x01, 0x23, 0x1f, 0x00, 0xaf, 0x40, 0x3d, 0x00, + 0x08, 0x31, 0x8b, 0x40, 0x06, 0x68, 0x35, 0x43, 0x05, 0x60, 0x05, 0x68, + 0x2b, 0x43, 0x03, 0x60, 0x1f, 0x23, 0x00, 0x19, 0x1a, 0x40, 0xd8, 0x30, + 0x02, 0x60, 0xf0, 0xbd, 0x80, 0x26, 0x76, 0x02, 0x2e, 0x60, 0xf8, 0x26, + 0x76, 0x02, 0x6e, 0x60, 0xc0, 0x26, 0x36, 0x03, 0xae, 0x60, 0xd1, 0xe7, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x48, 0x04, 0x21, 0x01, 0x4b, 0x18, 0x47, + 0x50, 0x05, 0x00, 0x20, 0xc9, 0x61, 0x00, 0x10, 0x10, 0xb5, 0x02, 0x48, + 0x02, 0xf0, 0xfe, 0xff, 0x10, 0xbd, 0xc0, 0x46, 0x29, 0x1c, 0x00, 0x20, + 0xf0, 0xb5, 0x00, 0x23, 0x01, 0x25, 0x0f, 0x26, 0x01, 0x39, 0x99, 0x42, + 0x01, 0xd9, 0x10, 0x2b, 0x02, 0xd1, 0x00, 0x22, 0xc2, 0x54, 0xf0, 0xbd, + 0x1f, 0x00, 0x09, 0x4c, 0x2f, 0x40, 0x5a, 0x08, 0xa2, 0x5c, 0x3c, 0x00, + 0x67, 0x42, 0x67, 0x41, 0xbf, 0x00, 0x3a, 0x41, 0x32, 0x40, 0xd4, 0xb2, + 0x27, 0x00, 0x37, 0x37, 0x09, 0x2a, 0x00, 0xdc, 0x07, 0x3f, 0xc7, 0x54, + 0x01, 0x33, 0xe4, 0xe7, 0x29, 0x1c, 0x00, 0x20, 0xf0, 0xb5, 0x85, 0xb0, + 0x06, 0x00, 0x0f, 0x00, 0x03, 0x92, 0x02, 0xf0, 0x59, 0xfe, 0x04, 0x1e, + 0x2a, 0xd1, 0x01, 0x22, 0x15, 0x4d, 0x11, 0x00, 0x2b, 0x00, 0x05, 0x20, + 0x00, 0x95, 0x02, 0xf0, 0x57, 0xfe, 0x03, 0x9b, 0x32, 0x00, 0x01, 0x21, + 0x11, 0x48, 0x00, 0x93, 0x3b, 0x00, 0x02, 0xf0, 0x55, 0xff, 0x03, 0x99, + 0x30, 0x00, 0x79, 0x43, 0x00, 0xf0, 0x42, 0xf9, 0x06, 0x00, 0x0d, 0x4b, + 0x22, 0x00, 0x02, 0x21, 0x00, 0x93, 0x04, 0x20, 0x02, 0xf0, 0x42, 0xfe, + 0x33, 0x00, 0x22, 0x00, 0x01, 0x21, 0x05, 0x20, 0x00, 0x96, 0x02, 0xf0, + 0x3b, 0xfe, 0x2b, 0x00, 0x02, 0x22, 0x21, 0x00, 0x06, 0x20, 0x00, 0x95, + 0x02, 0xf0, 0x34, 0xfe, 0x05, 0xb0, 0xf0, 0xbd, 0x00, 0x6c, 0xdc, 0x02, + 0x00, 0x80, 0x02, 0x40, 0x00, 0x1b, 0xb7, 0x00, 0xf0, 0xb5, 0x87, 0xb0, + 0x02, 0x90, 0x04, 0x20, 0x03, 0x91, 0x04, 0x92, 0x05, 0x93, 0x02, 0xf0, + 0x07, 0xff, 0xfa, 0x21, 0xa0, 0x26, 0x89, 0x00, 0x00, 0xf0, 0x16, 0xf9, + 0x32, 0x25, 0x76, 0x00, 0x46, 0x43, 0x01, 0x90, 0xff, 0x35, 0x17, 0x4b, + 0x17, 0x4a, 0xf3, 0x18, 0x07, 0x24, 0x93, 0x42, 0x0f, 0xd9, 0x01, 0x9b, + 0x01, 0x3d, 0xf6, 0x1a, 0x00, 0x2d, 0xf4, 0xd1, 0x28, 0x00, 0x1f, 0xe0, + 0x00, 0x9b, 0x01, 0x3f, 0x1b, 0x1b, 0x00, 0x93, 0x00, 0x2f, 0x06, 0xd1, + 0x01, 0x3c, 0x00, 0x2c, 0xef, 0xd0, 0x23, 0x00, 0x27, 0x00, 0x63, 0x43, + 0x00, 0x93, 0x30, 0x00, 0x00, 0x99, 0x00, 0xf0, 0xf3, 0xf8, 0x02, 0x9b, + 0x98, 0x42, 0xeb, 0xd1, 0x00, 0x29, 0xe9, 0xd1, 0xfa, 0x23, 0x01, 0x20, + 0x9b, 0x00, 0x5e, 0x43, 0x03, 0x9b, 0x1e, 0x60, 0x04, 0x9b, 0x1c, 0x60, + 0x05, 0x9b, 0x1f, 0x60, 0x07, 0xb0, 0xf0, 0xbd, 0x50, 0x8e, 0xf4, 0xff, + 0x50, 0xf8, 0x0c, 0x00, 0x23, 0x4b, 0x24, 0x4a, 0x70, 0xb5, 0x1a, 0x60, + 0x23, 0x4e, 0x24, 0x4b, 0x24, 0x4d, 0x33, 0x60, 0x19, 0x00, 0xaa, 0x68, + 0x91, 0x43, 0xfb, 0xd1, 0x22, 0x4c, 0x23, 0x4b, 0x9c, 0x42, 0x24, 0xd3, + 0x02, 0xf0, 0x3e, 0xfe, 0x21, 0x4b, 0x33, 0x60, 0xab, 0x68, 0xdb, 0x01, + 0x80, 0x33, 0xfb, 0xd1, 0x40, 0x22, 0x1f, 0x4b, 0x1f, 0x48, 0x9a, 0x67, + 0x5a, 0x67, 0x1a, 0x67, 0xda, 0x66, 0x1e, 0x4b, 0x98, 0x42, 0x15, 0xd3, + 0x1d, 0x4c, 0x1e, 0x4d, 0xa1, 0x68, 0xc0, 0x22, 0x28, 0x00, 0x00, 0xf0, + 0xb3, 0xff, 0xa5, 0x60, 0xfe, 0xf7, 0x02, 0xff, 0xff, 0xf7, 0x94, 0xf8, + 0xff, 0xf7, 0x56, 0xfa, 0x18, 0x4c, 0x19, 0x4b, 0x9c, 0x42, 0x0f, 0xd3, + 0x70, 0xbd, 0x08, 0xcc, 0x98, 0x47, 0xd4, 0xe7, 0x04, 0x00, 0x03, 0x68, + 0x08, 0x34, 0x00, 0x2b, 0x03, 0xd0, 0xff, 0xf7, 0xba, 0xfd, 0x20, 0x00, + 0xdd, 0xe7, 0xff, 0xf7, 0xa9, 0xfd, 0xfa, 0xe7, 0x08, 0xcc, 0x98, 0x47, + 0xe9, 0xe7, 0xc0, 0x46, 0x00, 0xe0, 0x00, 0x40, 0xbf, 0xcd, 0xfb, 0xfe, + 0x00, 0xf0, 0x00, 0x40, 0xfe, 0x7f, 0x3c, 0x00, 0x00, 0xc0, 0x00, 0x40, + 0x60, 0x0c, 0x00, 0x20, 0x70, 0x0c, 0x00, 0x20, 0xff, 0xff, 0xff, 0x01, + 0x00, 0xf0, 0x01, 0x40, 0x10, 0x0c, 0x00, 0x20, 0x60, 0x0c, 0x00, 0x20, + 0x00, 0xed, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x20, 0x70, 0x0c, 0x00, 0x20, + 0x84, 0x0c, 0x00, 0x20, 0x00, 0xbe, 0xfd, 0xe7, 0x08, 0x4a, 0x03, 0x00, + 0x11, 0x68, 0x00, 0x29, 0x01, 0xd1, 0x07, 0x49, 0x11, 0x60, 0x10, 0x68, + 0x06, 0x49, 0xc3, 0x18, 0x8b, 0x42, 0x01, 0xd8, 0x13, 0x60, 0x70, 0x47, + 0x01, 0x20, 0x40, 0x42, 0xfb, 0xe7, 0xc0, 0x46, 0x64, 0x14, 0x00, 0x20, + 0x34, 0x1c, 0x00, 0x20, 0x00, 0x00, 0x04, 0x20, 0x00, 0xbe, 0xfd, 0xe7, + 0x13, 0xb5, 0x0c, 0x00, 0x19, 0x00, 0x07, 0x4b, 0x00, 0x2a, 0x01, 0xd1, + 0x06, 0x4b, 0x1a, 0x00, 0x01, 0x92, 0x00, 0x93, 0x02, 0x00, 0x23, 0x00, + 0x04, 0x48, 0x04, 0xf0, 0xd1, 0xfc, 0x00, 0xbe, 0xfd, 0xe7, 0xc0, 0x46, + 0x49, 0x00, 0x01, 0x10, 0x11, 0xfd, 0x00, 0x10, 0x56, 0x00, 0x01, 0x10, + 0x0f, 0xb4, 0x07, 0xb5, 0x07, 0x48, 0x04, 0xf0, 0x41, 0xfd, 0x04, 0x9b, + 0x00, 0x2b, 0x07, 0xd0, 0x05, 0xa9, 0x18, 0x00, 0x01, 0x91, 0x05, 0xf0, + 0x43, 0xfe, 0x03, 0x48, 0x04, 0xf0, 0x36, 0xfd, 0x00, 0xbe, 0xfd, 0xe7, + 0x85, 0x00, 0x01, 0x10, 0x10, 0xfd, 0x00, 0x10, 0x10, 0xb5, 0x01, 0x48, + 0xff, 0xf7, 0xe6, 0xff, 0x95, 0x00, 0x01, 0x10, 0x12, 0x4a, 0x93, 0x6f, + 0x9b, 0x08, 0x15, 0xd2, 0x90, 0x66, 0xd1, 0x66, 0x00, 0x29, 0x05, 0xd0, + 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, 0x51, 0x6f, 0x10, 0x6f, 0x70, 0x47, + 0x04, 0xb5, 0x80, 0x21, 0x09, 0x06, 0xc2, 0x17, 0x51, 0x40, 0x00, 0x28, + 0x00, 0xd0, 0xc8, 0x43, 0x09, 0xf0, 0xc4, 0xfa, 0x00, 0x21, 0x04, 0xbd, + 0xf0, 0xb5, 0x14, 0x6e, 0x55, 0x6e, 0x57, 0x6f, 0x16, 0x6f, 0xff, 0xf7, + 0xe3, 0xff, 0x14, 0x66, 0x55, 0x66, 0x57, 0x67, 0x16, 0x67, 0xf0, 0xbd, + 0x00, 0x00, 0x00, 0xd0, 0x11, 0x4a, 0x93, 0x6f, 0x9b, 0x08, 0x13, 0xd2, + 0x10, 0x66, 0x51, 0x66, 0x00, 0x29, 0x05, 0xd0, 0xff, 0xe7, 0xff, 0xe7, + 0xff, 0xe7, 0x51, 0x6f, 0x10, 0x6f, 0x70, 0x47, 0x04, 0xb5, 0x00, 0x28, + 0x01, 0xd0, 0x00, 0x20, 0xc0, 0x43, 0x09, 0xf0, 0x9f, 0xfa, 0x00, 0x21, + 0x04, 0xbd, 0xc0, 0x46, 0xf0, 0xb5, 0x14, 0x6e, 0x55, 0x6e, 0x57, 0x6f, + 0x16, 0x6f, 0xff, 0xf7, 0xe5, 0xff, 0x14, 0x66, 0x55, 0x66, 0x57, 0x67, + 0x16, 0x67, 0xf0, 0xbd, 0x00, 0x00, 0x00, 0xd0, 0x94, 0x46, 0x4e, 0x4a, + 0x92, 0x6f, 0x92, 0x08, 0x62, 0x46, 0x01, 0xd2, 0x30, 0xe0, 0xc0, 0x46, + 0xf0, 0xb5, 0x4a, 0x4e, 0xb5, 0x6f, 0x6d, 0x08, 0xfc, 0xd3, 0x34, 0x6e, + 0x75, 0x6e, 0x77, 0x6f, 0x36, 0x6f, 0x00, 0xf0, 0x25, 0xf8, 0x94, 0x46, + 0x44, 0x4a, 0x14, 0x66, 0x55, 0x66, 0x57, 0x67, 0x16, 0x67, 0x62, 0x46, + 0xf0, 0xbd, 0xc0, 0x46, 0x94, 0x46, 0x40, 0x4a, 0x92, 0x6f, 0x92, 0x08, + 0x62, 0x46, 0x01, 0xd2, 0x58, 0xe0, 0xc0, 0x46, 0xf0, 0xb5, 0x3c, 0x4e, + 0xb5, 0x6f, 0x6d, 0x08, 0xfc, 0xd3, 0x34, 0x6e, 0x75, 0x6e, 0x77, 0x6f, + 0x36, 0x6f, 0x00, 0xf0, 0x4d, 0xf8, 0x94, 0x46, 0x36, 0x4a, 0x14, 0x66, + 0x55, 0x66, 0x57, 0x67, 0x16, 0x67, 0x62, 0x46, 0xf0, 0xbd, 0xc0, 0x46, + 0x00, 0x2b, 0x24, 0xdb, 0x11, 0xd0, 0x00, 0x29, 0x3e, 0xda, 0x00, 0xb5, + 0xc9, 0x43, 0x40, 0x42, 0x00, 0xd1, 0x01, 0x31, 0x00, 0xf0, 0x38, 0xf8, + 0xc9, 0x43, 0x40, 0x42, 0x00, 0xd1, 0x01, 0x31, 0xdb, 0x43, 0x52, 0x42, + 0x00, 0xd1, 0x01, 0x33, 0x00, 0xbd, 0x00, 0x2a, 0xeb, 0xd1, 0x00, 0x28, + 0x01, 0xd1, 0x00, 0x29, 0x05, 0xd0, 0x00, 0x20, 0xc9, 0x0f, 0xc9, 0x07, + 0x01, 0xd1, 0xc0, 0x43, 0x41, 0x08, 0x00, 0xb5, 0x09, 0xf0, 0x1a, 0xfa, + 0x00, 0x22, 0x00, 0x23, 0x00, 0xbd, 0x00, 0xb5, 0x00, 0x29, 0x0a, 0xdb, + 0xdb, 0x43, 0x52, 0x42, 0x00, 0xd1, 0x01, 0x33, 0x00, 0xf0, 0x14, 0xf8, + 0xc9, 0x43, 0x40, 0x42, 0x00, 0xd1, 0x01, 0x31, 0x00, 0xbd, 0xc9, 0x43, + 0x40, 0x42, 0x00, 0xd1, 0x01, 0x31, 0xdb, 0x43, 0x52, 0x42, 0x00, 0xd1, + 0x01, 0x33, 0x00, 0xf0, 0x05, 0xf8, 0xdb, 0x43, 0x52, 0x42, 0x00, 0xd1, + 0x01, 0x33, 0x00, 0xbd, 0x00, 0x29, 0x23, 0xd1, 0x00, 0x2b, 0x18, 0xd1, + 0x00, 0x2a, 0x0c, 0xd0, 0xbc, 0x46, 0x0d, 0x4f, 0x38, 0x66, 0x7a, 0x66, + 0x00, 0x21, 0x00, 0x23, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, 0x7a, 0x6f, + 0x38, 0x6f, 0x67, 0x46, 0x70, 0x47, 0x00, 0x28, 0x01, 0xd0, 0x07, 0x48, + 0x01, 0x00, 0x00, 0xb5, 0x09, 0xf0, 0xe0, 0xf9, 0x00, 0x22, 0x00, 0x23, + 0x00, 0xbd, 0x02, 0x00, 0x0b, 0x00, 0x00, 0x20, 0x00, 0x21, 0x70, 0x47, + 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0xff, 0xff, 0x00, 0x2b, 0x00, 0xd0, + 0xbf, 0xe0, 0x13, 0x0c, 0x28, 0xd1, 0x00, 0x2a, 0xe7, 0xd0, 0x80, 0xb4, + 0x11, 0x4f, 0x39, 0x66, 0x7a, 0x66, 0xff, 0xe7, 0xff, 0xe7, 0x30, 0xb4, + 0x04, 0x0c, 0x7b, 0x6f, 0x39, 0x6f, 0x1b, 0x04, 0x23, 0x43, 0x3b, 0x66, + 0x7a, 0x66, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, 0xc0, 0x46, 0x84, 0xb2, + 0x7b, 0x6f, 0x3d, 0x6f, 0x1b, 0x04, 0x23, 0x43, 0x3b, 0x66, 0x7a, 0x66, + 0xff, 0xe7, 0xff, 0xe7, 0xc0, 0x46, 0x00, 0x23, 0x2c, 0x04, 0x2d, 0x0c, + 0x7a, 0x6f, 0x38, 0x6f, 0x00, 0x19, 0x69, 0x41, 0xb0, 0xbc, 0x70, 0x47, + 0x00, 0x00, 0x00, 0xd0, 0xf0, 0xb5, 0x94, 0x46, 0x00, 0x25, 0x14, 0x0e, + 0x01, 0xd1, 0x12, 0x02, 0x08, 0x35, 0x14, 0x0f, 0x01, 0xd1, 0x12, 0x01, + 0x04, 0x35, 0x94, 0x0f, 0x01, 0xd1, 0x92, 0x00, 0x02, 0x35, 0xd4, 0x0f, + 0x01, 0xd1, 0x52, 0x00, 0x01, 0x35, 0xd4, 0x0b, 0x01, 0x34, 0x25, 0x4f, + 0x7c, 0x66, 0x25, 0x4c, 0x3c, 0x66, 0x0e, 0x0c, 0x93, 0xb2, 0xff, 0xe7, + 0xff, 0xe7, 0xff, 0xe7, 0x3c, 0x6f, 0x66, 0x43, 0x36, 0x0c, 0x77, 0x03, + 0xbe, 0x46, 0x73, 0x43, 0xdf, 0x0b, 0x5b, 0x04, 0xc0, 0x1a, 0xb9, 0x41, + 0x13, 0x0c, 0x73, 0x43, 0xdb, 0x18, 0xc9, 0x1a, 0xce, 0x08, 0x66, 0x43, + 0x36, 0x0c, 0xb6, 0x44, 0x93, 0xb2, 0x73, 0x43, 0x1f, 0x0f, 0x1b, 0x01, + 0xc0, 0x1a, 0xb9, 0x41, 0x13, 0x0c, 0x73, 0x43, 0x1f, 0x0b, 0x1b, 0x05, + 0xc0, 0x1a, 0xb9, 0x41, 0x86, 0x0d, 0x8f, 0x02, 0x3e, 0x43, 0x66, 0x43, + 0x36, 0x0c, 0x09, 0x2d, 0x24, 0xdb, 0x52, 0x0a, 0x72, 0x43, 0x80, 0x1a, + 0x77, 0x03, 0x46, 0x0a, 0x66, 0x43, 0x36, 0x0c, 0x16, 0x23, 0x5b, 0x1b, + 0xde, 0x40, 0xdf, 0x40, 0xbf, 0x19, 0x64, 0x46, 0x66, 0x43, 0x82, 0x1b, + 0x70, 0x46, 0x04, 0x35, 0x06, 0x33, 0x01, 0x00, 0xd9, 0x40, 0xa8, 0x40, + 0xc0, 0x19, 0x00, 0xd3, 0x01, 0x31, 0xa2, 0x42, 0x06, 0xd2, 0x00, 0x23, + 0xf0, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xff, 0xff, 0xff, 0xff, + 0x12, 0x1b, 0x01, 0x30, 0xf3, 0xd3, 0xf1, 0xe7, 0x09, 0x27, 0x7f, 0x1b, + 0xfe, 0x40, 0x64, 0x46, 0xa2, 0xb2, 0x72, 0x43, 0x80, 0x1a, 0x00, 0xd2, + 0x01, 0x39, 0x22, 0x0c, 0x72, 0x43, 0x13, 0x0c, 0x12, 0x04, 0x82, 0x1a, + 0x99, 0x41, 0x0b, 0x00, 0x70, 0x46, 0x04, 0x35, 0x13, 0x37, 0x01, 0x00, + 0xf9, 0x40, 0xa8, 0x40, 0x80, 0x19, 0x00, 0xd3, 0x01, 0x31, 0x00, 0x2b, + 0x02, 0xd1, 0xa2, 0x42, 0x0a, 0xd2, 0xf0, 0xbd, 0x01, 0x30, 0x00, 0xd3, + 0x01, 0x31, 0x12, 0x1b, 0xfa, 0xd2, 0x01, 0x3b, 0xf8, 0xd1, 0xa2, 0x42, + 0x00, 0xd2, 0xf0, 0xbd, 0x01, 0x30, 0x00, 0xd3, 0x01, 0x31, 0x12, 0x1b, + 0xf7, 0xe7, 0xf0, 0xb5, 0x1c, 0x0c, 0x00, 0xd0, 0x80, 0xe0, 0x0c, 0xb4, + 0x00, 0x25, 0x1c, 0x0a, 0x04, 0xd1, 0x1b, 0x02, 0x16, 0x0e, 0x33, 0x43, + 0x12, 0x02, 0x08, 0x35, 0x1c, 0x0b, 0x04, 0xd1, 0x1b, 0x01, 0x16, 0x0f, + 0x33, 0x43, 0x12, 0x01, 0x04, 0x35, 0x9c, 0x0b, 0x04, 0xd1, 0x9b, 0x00, + 0x96, 0x0f, 0x33, 0x43, 0x92, 0x00, 0x02, 0x35, 0xdc, 0x0b, 0x02, 0xd1, + 0x92, 0x18, 0x5b, 0x41, 0x01, 0x35, 0x1c, 0x00, 0x97, 0x18, 0x64, 0x41, + 0x01, 0x34, 0x46, 0x4f, 0x7c, 0x66, 0x46, 0x4c, 0x3c, 0x66, 0x0e, 0x0c, + 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, 0xc0, 0x46, 0x3c, 0x6f, 0x66, 0x43, + 0x36, 0x0c, 0x77, 0x03, 0xbe, 0x46, 0x97, 0xb2, 0x77, 0x43, 0xc0, 0x1b, + 0x00, 0xd2, 0x01, 0x39, 0xc0, 0x1b, 0x00, 0xd2, 0x01, 0x39, 0x9f, 0xb2, + 0x77, 0x43, 0xc9, 0x1b, 0xc9, 0x1b, 0x17, 0x0c, 0x77, 0x43, 0x7e, 0x04, + 0xff, 0x0b, 0x80, 0x1b, 0xb9, 0x41, 0xce, 0x08, 0x66, 0x43, 0x36, 0x0c, + 0x0c, 0x2d, 0x33, 0xdb, 0xb6, 0x44, 0x12, 0x0b, 0x1f, 0x05, 0x3a, 0x43, + 0x1b, 0x0b, 0x97, 0xb2, 0x77, 0x43, 0xc0, 0x1b, 0x00, 0xd2, 0x01, 0x39, + 0x9f, 0xb2, 0x77, 0x43, 0xc9, 0x1b, 0x17, 0x0c, 0x77, 0x43, 0x3e, 0x04, + 0x3f, 0x0c, 0x80, 0x1b, 0xb9, 0x41, 0x86, 0x0d, 0x8f, 0x02, 0x3e, 0x43, + 0x66, 0x43, 0x29, 0x27, 0x7f, 0x1b, 0xfe, 0x40, 0x0c, 0x3d, 0x77, 0x46, + 0xaf, 0x40, 0xbf, 0x19, 0x30, 0xbc, 0xa2, 0xb2, 0xab, 0xb2, 0x72, 0x43, + 0x73, 0x43, 0x80, 0x1a, 0x99, 0x41, 0x22, 0x0c, 0x72, 0x43, 0x13, 0x0c, + 0x12, 0x04, 0x80, 0x1a, 0x99, 0x41, 0x02, 0x00, 0x0b, 0x00, 0x01, 0x37, + 0x00, 0x1b, 0xa9, 0x41, 0xf9, 0xd2, 0x78, 0x1e, 0x00, 0x21, 0xf0, 0xbd, + 0x0c, 0x27, 0x7f, 0x1b, 0xfe, 0x40, 0x77, 0x46, 0x7f, 0x0b, 0xaf, 0x40, + 0xff, 0x19, 0xe0, 0xe7, 0x00, 0x24, 0x5d, 0x1c, 0x07, 0xd0, 0x14, 0x4f, + 0x7d, 0x66, 0x39, 0x66, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, + 0x3c, 0x6f, 0x95, 0xb2, 0x9e, 0xb2, 0x65, 0x43, 0x66, 0x43, 0x40, 0x1b, + 0xb1, 0x41, 0x15, 0x0c, 0x1e, 0x0c, 0x65, 0x43, 0x66, 0x43, 0x36, 0x04, + 0x2f, 0x0c, 0x3e, 0x43, 0x2d, 0x04, 0x40, 0x1b, 0xb1, 0x41, 0x99, 0x42, + 0x04, 0xd2, 0x02, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x00, 0x21, 0xf0, 0xbd, + 0x01, 0xd1, 0x90, 0x42, 0xf7, 0xd3, 0x80, 0x1a, 0x99, 0x41, 0x01, 0x34, + 0x99, 0x42, 0xf2, 0xd3, 0xf6, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, + 0xff, 0xff, 0xff, 0xff, 0x48, 0x40, 0x41, 0x40, 0x48, 0x40, 0x18, 0xb4, + 0x1b, 0x4b, 0x5b, 0x68, 0xfc, 0x46, 0x01, 0x93, 0x08, 0xbd, 0x04, 0xdf, + 0x7b, 0x6e, 0x00, 0x10, 0x18, 0xb4, 0x17, 0x4b, 0x1b, 0x68, 0xfc, 0x46, + 0x01, 0x93, 0x08, 0xbd, 0x00, 0xdf, 0x85, 0x6e, 0x00, 0x10, 0x94, 0x46, + 0x13, 0x4a, 0x92, 0x6f, 0x92, 0x08, 0x09, 0xd2, 0x62, 0x46, 0x18, 0xb4, + 0x0f, 0x4b, 0xdb, 0x68, 0xfc, 0x46, 0x01, 0x93, 0x08, 0xbd, 0x0c, 0xdf, + 0x3d, 0x71, 0x00, 0x10, 0x0c, 0x4a, 0xf0, 0xb5, 0x14, 0x6e, 0x55, 0x6e, + 0x57, 0x6f, 0x16, 0x6f, 0x62, 0x46, 0xff, 0xf7, 0xee, 0xff, 0x08, 0x4a, + 0x14, 0x66, 0x55, 0x66, 0x57, 0x67, 0x16, 0x67, 0xf0, 0xbd, 0x18, 0xb4, + 0x03, 0x4b, 0x9b, 0x68, 0xfc, 0x46, 0x01, 0x93, 0x08, 0xbd, 0x08, 0xdf, + 0xe1, 0x6f, 0x00, 0x10, 0x7c, 0x18, 0x00, 0x20, 0x00, 0x00, 0x00, 0xd0, + 0xff, 0xb5, 0x50, 0x40, 0x42, 0x40, 0x50, 0x40, 0x59, 0x40, 0x4b, 0x40, + 0x59, 0x40, 0x00, 0xe0, 0xff, 0xb5, 0x15, 0x4f, 0x4c, 0x00, 0x64, 0x0d, + 0x03, 0xd0, 0xbc, 0x42, 0x04, 0xd1, 0x0c, 0x03, 0x14, 0xd8, 0x00, 0x20, + 0x09, 0x0d, 0x09, 0x05, 0x5c, 0x00, 0x64, 0x0d, 0x03, 0xd0, 0xbc, 0x42, + 0x04, 0xd1, 0x1c, 0x03, 0x0a, 0xd8, 0x00, 0x22, 0x1b, 0x0d, 0x1b, 0x05, + 0x01, 0x26, 0x4b, 0x40, 0x09, 0xd4, 0x4b, 0x40, 0x03, 0xd5, 0x8b, 0x42, + 0x00, 0xd1, 0x82, 0x42, 0xff, 0xbd, 0x99, 0x42, 0xfc, 0xd1, 0x90, 0x42, + 0xff, 0xbd, 0x0b, 0x43, 0xdb, 0x18, 0x03, 0x43, 0x13, 0x43, 0xf5, 0xd0, + 0xc9, 0x43, 0x49, 0x18, 0xff, 0xbd, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, + 0x00, 0xb5, 0xff, 0xf7, 0xcf, 0xff, 0x01, 0xd0, 0x00, 0x20, 0x00, 0xbd, + 0x01, 0x20, 0x00, 0xbd, 0x00, 0xb5, 0xff, 0xf7, 0xc7, 0xff, 0x80, 0x41, + 0x00, 0xbd, 0xc0, 0x46, 0x00, 0xb5, 0xff, 0xf7, 0xc1, 0xff, 0x01, 0xd9, + 0x00, 0x20, 0x00, 0xbd, 0x01, 0x20, 0x00, 0xbd, 0x00, 0xb5, 0xff, 0xf7, + 0xb1, 0xff, 0x01, 0xd9, 0x00, 0x20, 0x00, 0xbd, 0x01, 0x20, 0x00, 0xbd, + 0x00, 0xb5, 0xff, 0xf7, 0xa9, 0xff, 0x80, 0x41, 0x00, 0xbd, 0x01, 0x20, + 0x40, 0x05, 0x4a, 0x00, 0x12, 0x18, 0x04, 0xd8, 0x5a, 0x00, 0x12, 0x18, + 0x01, 0xd8, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, 0x70, 0x47, 0x00, 0x20, + 0x70, 0x47, 0x00, 0x00, 0x00, 0x21, 0x00, 0x28, 0x05, 0xd1, 0x70, 0x47, + 0xc1, 0x17, 0x48, 0x40, 0x40, 0x1a, 0xfa, 0xd0, 0xc9, 0x07, 0x13, 0xb5, + 0x06, 0x4b, 0x1b, 0x68, 0x98, 0x47, 0x0c, 0xbc, 0x44, 0x1c, 0xa2, 0x40, + 0x10, 0x05, 0x12, 0x0b, 0x03, 0x49, 0x09, 0x1b, 0x09, 0x05, 0x19, 0x43, + 0x11, 0x43, 0x10, 0xbd, 0x7c, 0x19, 0x00, 0x20, 0x1f, 0x04, 0x00, 0x00, + 0x10, 0xb5, 0x4c, 0x00, 0x62, 0x0d, 0x80, 0x23, 0xd2, 0x18, 0xdb, 0x00, + 0xd2, 0x1a, 0x5b, 0x05, 0x7e, 0x2a, 0x10, 0xdd, 0x9e, 0x3a, 0x13, 0xda, + 0xcc, 0x17, 0x09, 0x03, 0x49, 0x08, 0x19, 0x43, 0x52, 0x42, 0xd1, 0x40, + 0x64, 0x00, 0x01, 0x34, 0x15, 0x32, 0x20, 0x2a, 0x05, 0xda, 0xd0, 0x40, + 0x08, 0x43, 0x60, 0x43, 0x10, 0xbd, 0x00, 0x20, 0x10, 0xbd, 0x08, 0x46, + 0x60, 0x43, 0x10, 0xbd, 0xc8, 0x0f, 0xc0, 0x18, 0x01, 0x38, 0x10, 0xbd, + 0x18, 0xb4, 0x04, 0x4b, 0x5b, 0x6a, 0xfc, 0x46, 0x01, 0x93, 0x08, 0xbd, + 0x24, 0xdf, 0xed, 0x72, 0x00, 0x10, 0x00, 0x00, 0x7c, 0x18, 0x00, 0x20, + 0x18, 0xb4, 0x04, 0x4b, 0xdb, 0x6d, 0xfc, 0x46, 0x01, 0x93, 0x08, 0xbd, + 0x5c, 0xdf, 0xf9, 0x73, 0x00, 0x10, 0x00, 0x00, 0x7c, 0x18, 0x00, 0x20, + 0xc9, 0x42, 0x11, 0xd3, 0x00, 0xb5, 0x49, 0x00, 0x49, 0x08, 0x00, 0x22, + 0x00, 0xf0, 0x18, 0xf8, 0x00, 0x29, 0x04, 0xd4, 0x00, 0x22, 0x40, 0x42, + 0x8a, 0x41, 0x11, 0x46, 0x00, 0xbd, 0x80, 0x21, 0x09, 0x06, 0x00, 0x20, + 0x00, 0xbd, 0x00, 0x00, 0x18, 0xb4, 0x04, 0x4b, 0xdb, 0x6e, 0xfc, 0x46, + 0x01, 0x93, 0x08, 0xbd, 0x6c, 0xdf, 0xfb, 0x72, 0x00, 0x10, 0x00, 0x00, + 0x7c, 0x18, 0x00, 0x20, 0x18, 0xb4, 0x04, 0x4b, 0x9b, 0x6f, 0xfc, 0x46, + 0x01, 0x93, 0x08, 0xbd, 0x78, 0xdf, 0x17, 0x73, 0x00, 0x10, 0x00, 0x00, + 0x7c, 0x18, 0x00, 0x20, 0x18, 0xb4, 0x04, 0x4b, 0xdb, 0x6f, 0xfc, 0x46, + 0x01, 0x93, 0x08, 0xbd, 0x7c, 0xdf, 0x85, 0x73, 0x00, 0x10, 0x00, 0x00, + 0x7c, 0x18, 0x00, 0x20, 0x13, 0x23, 0x70, 0xb5, 0x1c, 0x78, 0x0f, 0x4d, + 0x01, 0x2c, 0x0e, 0xd1, 0x00, 0x23, 0x0e, 0x49, 0x9a, 0x00, 0x01, 0x33, + 0xa9, 0x50, 0x20, 0x2b, 0xfa, 0xd1, 0x0b, 0x4b, 0xab, 0x64, 0x0b, 0x48, + 0xff, 0xf7, 0xca, 0xf9, 0x0a, 0x4b, 0x18, 0x60, 0x70, 0xbd, 0x01, 0x2c, + 0xf5, 0xdd, 0x09, 0x48, 0xff, 0xf7, 0xca, 0xf9, 0x80, 0x22, 0x01, 0x00, + 0x28, 0x00, 0x00, 0xf0, 0x67, 0xfb, 0x02, 0x2c, 0xed, 0xd1, 0xea, 0xe7, + 0x7c, 0x18, 0x00, 0x20, 0x49, 0x6e, 0x00, 0x10, 0x4c, 0x33, 0x00, 0x00, + 0x7c, 0x19, 0x00, 0x20, 0x53, 0x44, 0x00, 0x00, 0x07, 0xb5, 0x60, 0x46, + 0x01, 0x88, 0x0a, 0x0a, 0x02, 0x30, 0xdf, 0x2a, 0xfa, 0xd1, 0xc9, 0xb2, + 0x82, 0x08, 0x04, 0xd3, 0x02, 0x88, 0x40, 0x88, 0x00, 0x04, 0x10, 0x43, + 0x00, 0xe0, 0x00, 0x68, 0x01, 0x4a, 0x50, 0x50, 0x03, 0x90, 0x07, 0xbd, + 0x7c, 0x18, 0x00, 0x20, 0x0f, 0xb4, 0x03, 0xbc, 0x0c, 0xbc, 0xf0, 0xb5, + 0x01, 0x24, 0xe4, 0x07, 0x63, 0x40, 0x00, 0xe0, 0xf0, 0xb5, 0x0c, 0x0d, + 0xcf, 0x0f, 0x66, 0x1e, 0x36, 0x05, 0x89, 0x1b, 0x64, 0x05, 0x03, 0xd3, + 0xc9, 0x43, 0x40, 0x42, 0x00, 0xd3, 0x01, 0x31, 0x64, 0x0d, 0x03, 0xd0, + 0x66, 0x1c, 0xf6, 0x0a, 0x07, 0xd0, 0xe4, 0x1b, 0x00, 0x20, 0x7f, 0x00, + 0x79, 0x1c, 0x89, 0x07, 0x89, 0x12, 0x80, 0x3c, 0x24, 0x03, 0x1d, 0x0d, + 0xdf, 0x0f, 0x6e, 0x1e, 0x36, 0x05, 0x9b, 0x1b, 0x6d, 0x05, 0x03, 0xd3, + 0xdb, 0x43, 0x52, 0x42, 0x00, 0xd3, 0x01, 0x33, 0x6d, 0x0d, 0x03, 0xd0, + 0x6e, 0x1c, 0xf6, 0x0a, 0x07, 0xd0, 0xed, 0x1b, 0x00, 0x22, 0x7f, 0x00, + 0x7b, 0x1c, 0x9b, 0x07, 0x9b, 0x12, 0x80, 0x3d, 0x2d, 0x03, 0x2f, 0x1b, + 0x66, 0x1b, 0x58, 0xd4, 0xa4, 0x46, 0x20, 0x2e, 0x46, 0xda, 0x20, 0x37, + 0x14, 0x00, 0xbc, 0x40, 0x1d, 0x00, 0xbd, 0x40, 0xf2, 0x40, 0x33, 0x41, + 0x2a, 0x43, 0x80, 0x18, 0x59, 0x41, 0xcb, 0x0f, 0x05, 0xd0, 0xc9, 0x43, + 0xc0, 0x43, 0x00, 0x22, 0x64, 0x42, 0x50, 0x41, 0x51, 0x41, 0x62, 0x46, + 0x4d, 0x0d, 0x28, 0xd1, 0x0d, 0x0d, 0x07, 0xd1, 0x00, 0x28, 0x1f, 0xd0, + 0x24, 0x19, 0x40, 0x41, 0x49, 0x41, 0x01, 0x3a, 0x0d, 0x0d, 0xf9, 0xd0, + 0x64, 0x00, 0x06, 0xd3, 0x01, 0x30, 0x00, 0xd3, 0x01, 0x31, 0x00, 0x2c, + 0x01, 0xd1, 0x40, 0x08, 0x40, 0x00, 0x01, 0x3a, 0x0b, 0xd4, 0x94, 0x1c, + 0xe4, 0x0a, 0x04, 0xd1, 0x12, 0x05, 0x11, 0x44, 0xdb, 0x07, 0x19, 0x44, + 0xf0, 0xbd, 0xd9, 0x07, 0x20, 0x4b, 0x19, 0x43, 0x00, 0xe0, 0xd9, 0x07, + 0x00, 0x20, 0xf0, 0xbd, 0x00, 0x29, 0xdd, 0xd1, 0x00, 0x2c, 0xdb, 0xd1, + 0xf0, 0xbd, 0x01, 0x32, 0xc6, 0x07, 0x40, 0x08, 0xcd, 0x07, 0x28, 0x43, + 0x49, 0x08, 0x00, 0x2e, 0xe1, 0xd0, 0xd9, 0xe7, 0x3c, 0x2e, 0x29, 0xda, + 0x20, 0x3e, 0x40, 0x37, 0x14, 0x00, 0xbc, 0x40, 0x00, 0xd0, 0x01, 0x24, + 0xf2, 0x40, 0x14, 0x43, 0x1a, 0x00, 0xbb, 0x40, 0x1c, 0x43, 0xd3, 0x17, + 0xac, 0xe7, 0xac, 0x46, 0x20, 0x2f, 0x08, 0xda, 0x20, 0x36, 0x04, 0x00, + 0xb4, 0x40, 0x0d, 0x00, 0xb5, 0x40, 0xf8, 0x40, 0x39, 0x41, 0x28, 0x43, + 0xa5, 0xe7, 0x3c, 0x2f, 0x0c, 0xda, 0x20, 0x3f, 0x40, 0x36, 0x04, 0x00, + 0xb4, 0x40, 0x00, 0xd0, 0x01, 0x24, 0xf8, 0x40, 0x04, 0x43, 0x08, 0x00, + 0xb1, 0x40, 0x0c, 0x43, 0xc1, 0x17, 0xea, 0xe7, 0x10, 0x00, 0x19, 0x00, + 0x00, 0x24, 0x94, 0xe7, 0x00, 0x00, 0xf0, 0x7f, 0xf0, 0xb5, 0x0c, 0x0d, + 0x66, 0x1e, 0x36, 0x05, 0x89, 0x1b, 0xe6, 0x0a, 0x64, 0x05, 0x64, 0x0d, + 0x02, 0xd0, 0x65, 0x1c, 0xed, 0x0a, 0x04, 0xd0, 0x00, 0x20, 0x01, 0x21, + 0x09, 0x05, 0x80, 0x3c, 0x24, 0x03, 0xa4, 0x46, 0x1c, 0x0d, 0x67, 0x1e, + 0x3f, 0x05, 0xdb, 0x1b, 0xe7, 0x0a, 0x64, 0x05, 0x64, 0x0d, 0x02, 0xd0, + 0x65, 0x1c, 0xed, 0x0a, 0x04, 0xd0, 0x00, 0x22, 0x01, 0x23, 0x1b, 0x05, + 0x80, 0x3c, 0x24, 0x03, 0x77, 0x40, 0x64, 0x44, 0x97, 0xb4, 0x84, 0xb2, + 0x96, 0xb2, 0x74, 0x43, 0x07, 0x0c, 0x7e, 0x43, 0x15, 0x0c, 0x6f, 0x43, + 0x80, 0xb2, 0x68, 0x43, 0x36, 0x18, 0x02, 0xd3, 0x01, 0x20, 0x00, 0x04, + 0x3f, 0x18, 0x30, 0x04, 0x35, 0x0c, 0x00, 0x19, 0x7d, 0x41, 0x84, 0x46, + 0x88, 0xb2, 0x9a, 0xb2, 0x50, 0x43, 0x0c, 0x0c, 0x62, 0x43, 0x1f, 0x0c, + 0x7c, 0x43, 0x8e, 0xb2, 0x7e, 0x43, 0x92, 0x19, 0x02, 0xd3, 0x01, 0x26, + 0x36, 0x04, 0xa4, 0x19, 0x16, 0x04, 0x17, 0x0c, 0x36, 0x18, 0x67, 0x41, + 0x01, 0xbc, 0x81, 0xb2, 0x9a, 0xb2, 0x51, 0x43, 0x04, 0x0c, 0x62, 0x43, + 0x1b, 0x0c, 0x5c, 0x43, 0x80, 0xb2, 0x58, 0x43, 0x12, 0x18, 0x02, 0xd3, + 0x01, 0x20, 0x00, 0x04, 0x24, 0x18, 0x10, 0x04, 0x13, 0x0c, 0x40, 0x18, + 0x63, 0x41, 0x2d, 0x18, 0x5e, 0x41, 0x00, 0x20, 0x47, 0x41, 0x06, 0xbc, + 0x88, 0xb2, 0x93, 0xb2, 0x58, 0x43, 0x0c, 0x0c, 0x63, 0x43, 0x12, 0x0c, + 0x54, 0x43, 0x89, 0xb2, 0x51, 0x43, 0x5b, 0x18, 0x02, 0xd3, 0x01, 0x21, + 0x09, 0x04, 0x64, 0x18, 0x19, 0x04, 0x1a, 0x0c, 0x09, 0x18, 0x62, 0x41, + 0x6d, 0x18, 0x56, 0x41, 0x00, 0x20, 0x47, 0x41, 0x18, 0xbc, 0xf9, 0x02, + 0x72, 0x0d, 0x11, 0x43, 0xf0, 0x02, 0x6a, 0x0d, 0x10, 0x43, 0xed, 0x02, + 0x0a, 0x0d, 0x03, 0xd1, 0x6d, 0x19, 0x40, 0x41, 0x49, 0x41, 0x01, 0x3b, + 0x12, 0x4e, 0x9b, 0x1b, 0x76, 0x00, 0xb3, 0x42, 0x0e, 0xd2, 0x6d, 0x00, + 0x07, 0xd3, 0x01, 0x30, 0x00, 0x26, 0x71, 0x41, 0x66, 0x46, 0x35, 0x43, + 0x01, 0xd1, 0x40, 0x08, 0x40, 0x00, 0x1b, 0x05, 0xc9, 0x18, 0xe4, 0x07, + 0x21, 0x44, 0xf0, 0xbd, 0x0b, 0xda, 0x01, 0x33, 0x06, 0xd1, 0x01, 0x30, + 0x04, 0xd1, 0x01, 0x31, 0x4f, 0x0d, 0x01, 0xd0, 0x49, 0x08, 0xf2, 0xe7, + 0xe1, 0x07, 0x00, 0x20, 0xf0, 0xbd, 0x01, 0x36, 0x31, 0x05, 0x00, 0x20, + 0xeb, 0xe7, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0xf0, 0xb5, 0x1c, 0x0d, + 0x67, 0x1e, 0x3f, 0x05, 0xdb, 0x1b, 0xe7, 0x0a, 0x64, 0x05, 0x64, 0x0d, + 0x02, 0xd0, 0x66, 0x1c, 0xf6, 0x0a, 0x04, 0xd0, 0x00, 0x22, 0x01, 0x23, + 0x1b, 0x05, 0x80, 0x3c, 0x24, 0x03, 0xd0, 0x25, 0x2d, 0x06, 0x00, 0x26, + 0xf6, 0x43, 0x2e, 0x66, 0x1e, 0x09, 0x6e, 0x66, 0xce, 0x0f, 0xf6, 0x19, + 0xb4, 0x46, 0x49, 0x00, 0x4f, 0x0d, 0x02, 0xd0, 0x7e, 0x1c, 0xf6, 0x0a, + 0x03, 0xd0, 0x00, 0x20, 0x00, 0x21, 0x40, 0x3f, 0x3f, 0x03, 0x3e, 0x1b, + 0xb6, 0x00, 0xb4, 0x44, 0x01, 0x3f, 0x7f, 0x05, 0xc9, 0x1b, 0x49, 0x08, + 0x2e, 0x6f, 0x01, 0x36, 0x76, 0x08, 0x9c, 0x02, 0x95, 0x0d, 0x25, 0x43, + 0x75, 0x43, 0xed, 0x13, 0x75, 0x43, 0xad, 0x13, 0x01, 0x35, 0x6d, 0x10, + 0xf6, 0x03, 0x76, 0x1b, 0x0c, 0xb4, 0xcc, 0x02, 0x45, 0x0d, 0x2c, 0x43, + 0xa2, 0xb2, 0xb3, 0xb2, 0x5a, 0x43, 0x27, 0x0c, 0x7b, 0x43, 0x35, 0x0c, + 0x6f, 0x43, 0xa4, 0xb2, 0x6c, 0x43, 0x1b, 0x19, 0x02, 0xd3, 0x01, 0x24, + 0x24, 0x04, 0x3f, 0x19, 0x1c, 0x04, 0x1d, 0x0c, 0xa4, 0x18, 0x7d, 0x41, + 0x24, 0x19, 0x6d, 0x41, 0x00, 0x9a, 0x91, 0xb2, 0xac, 0xb2, 0x61, 0x43, + 0x17, 0x0c, 0x7c, 0x43, 0x2b, 0x0c, 0x5f, 0x43, 0x92, 0xb2, 0x5a, 0x43, + 0xa4, 0x18, 0x02, 0xd3, 0x01, 0x22, 0x12, 0x04, 0xbf, 0x18, 0x22, 0x04, + 0x23, 0x0c, 0x52, 0x18, 0x7b, 0x41, 0x01, 0x9c, 0x6c, 0x43, 0x1b, 0x19, + 0x52, 0x0e, 0xd9, 0x01, 0x0a, 0x43, 0x44, 0x01, 0xa0, 0x1a, 0x81, 0xb2, + 0xb2, 0xb2, 0x51, 0x43, 0x03, 0x14, 0x5a, 0x43, 0x36, 0x0c, 0x73, 0x43, + 0x87, 0xb2, 0x77, 0x43, 0xd6, 0x17, 0xd2, 0x19, 0x00, 0x27, 0x7e, 0x41, + 0x36, 0x04, 0x9b, 0x19, 0x17, 0x04, 0x16, 0x0c, 0x7f, 0x18, 0x5e, 0x41, + 0x73, 0x16, 0xed, 0x18, 0xf3, 0x01, 0x00, 0x26, 0x80, 0x33, 0x75, 0x41, + 0xa9, 0x0f, 0x06, 0xd1, 0x64, 0x00, 0x69, 0x0a, 0xe8, 0x05, 0x5b, 0x0a, + 0x18, 0x43, 0x09, 0xd2, 0x2f, 0xe0, 0x04, 0x22, 0x94, 0x44, 0x80, 0x33, + 0x75, 0x41, 0xa9, 0x0a, 0xa8, 0x05, 0x9b, 0x0a, 0x18, 0x43, 0x26, 0xd3, + 0x40, 0x41, 0x49, 0x41, 0x24, 0x04, 0x00, 0x9a, 0x01, 0x9b, 0x0d, 0x00, + 0x55, 0x43, 0x64, 0x1b, 0x43, 0x43, 0xe4, 0x1a, 0x95, 0xb2, 0x86, 0xb2, + 0x75, 0x43, 0x17, 0x0c, 0x7e, 0x43, 0x03, 0x0c, 0x5f, 0x43, 0x92, 0xb2, + 0x5a, 0x43, 0xb6, 0x18, 0x02, 0xd3, 0x01, 0x22, 0x12, 0x04, 0xbf, 0x18, + 0x32, 0x04, 0x33, 0x0c, 0x52, 0x19, 0x7b, 0x41, 0x52, 0x42, 0x9c, 0x41, + 0x00, 0x2c, 0x02, 0xd4, 0x00, 0x22, 0x01, 0x30, 0x51, 0x41, 0x40, 0x08, + 0xca, 0x07, 0x10, 0x43, 0x49, 0x08, 0x02, 0xb0, 0x62, 0x46, 0xd7, 0x07, + 0x92, 0x10, 0x08, 0x4b, 0xd2, 0x18, 0x08, 0x4b, 0x9a, 0x42, 0x03, 0xd2, + 0x12, 0x05, 0x89, 0x18, 0xc9, 0x19, 0xf0, 0xbd, 0x00, 0x20, 0x00, 0x2a, + 0x01, 0xdc, 0x39, 0x00, 0xf0, 0xbd, 0x01, 0x33, 0x19, 0x05, 0xf5, 0xe7, + 0xfd, 0x03, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, 0x00, 0x22, 0x00, 0xb5, + 0x20, 0x32, 0x00, 0xf0, 0x10, 0xf8, 0x08, 0x00, 0x00, 0xbd, 0x00, 0x22, + 0x00, 0xb5, 0x00, 0xf0, 0x0c, 0xf8, 0xca, 0x17, 0x9a, 0x42, 0x00, 0xd1, + 0x00, 0xbd, 0xd8, 0x43, 0x01, 0x21, 0xc9, 0x07, 0x41, 0x40, 0x00, 0xbd, + 0x00, 0x22, 0x0b, 0x15, 0x0a, 0xd4, 0x10, 0xb5, 0x94, 0x46, 0x00, 0xf0, + 0xa7, 0xf8, 0x14, 0x14, 0x01, 0x34, 0x00, 0xda, 0x00, 0x21, 0xcb, 0x17, + 0x14, 0x4c, 0x20, 0x47, 0x00, 0x20, 0x00, 0x21, 0x70, 0x47, 0x62, 0x44, + 0x34, 0x3a, 0x0c, 0xd4, 0x0c, 0x2a, 0x07, 0xda, 0x04, 0x00, 0x91, 0x40, + 0x90, 0x40, 0x52, 0x42, 0x20, 0x32, 0xd4, 0x40, 0x21, 0x43, 0x10, 0xbd, + 0xd8, 0x43, 0xd9, 0x43, 0x10, 0xbd, 0x20, 0x32, 0x07, 0xd4, 0x0c, 0x46, + 0x94, 0x40, 0x52, 0x42, 0x20, 0x32, 0x11, 0x41, 0xd0, 0x40, 0x20, 0x43, + 0x10, 0xbd, 0x08, 0x00, 0xc9, 0x17, 0x20, 0x32, 0x03, 0xd4, 0x52, 0x42, + 0x20, 0x32, 0x10, 0x41, 0x10, 0xbd, 0x18, 0x00, 0x19, 0x00, 0x10, 0xbd, + 0x37, 0x73, 0x00, 0x10, 0x4a, 0x00, 0x52, 0x0d, 0x14, 0x4b, 0xd2, 0x1a, + 0x13, 0xdd, 0xff, 0x2a, 0x1e, 0xda, 0xd2, 0x05, 0xcb, 0x0f, 0xdb, 0x07, + 0x1a, 0x43, 0xc3, 0x00, 0x40, 0x0f, 0x09, 0x03, 0x49, 0x0a, 0x08, 0x43, + 0x10, 0x43, 0x5b, 0x00, 0x01, 0xd3, 0x01, 0xd0, 0x01, 0x30, 0x70, 0x47, + 0x43, 0x08, 0xfb, 0xd2, 0x70, 0x47, 0x02, 0xd0, 0xc8, 0x0f, 0xc0, 0x07, + 0x70, 0x47, 0x0a, 0x03, 0x12, 0x13, 0x01, 0x32, 0xf8, 0xd1, 0x42, 0x0f, + 0x07, 0x2a, 0xf5, 0xd1, 0x01, 0x22, 0x00, 0xe0, 0xff, 0x22, 0xc8, 0x0f, + 0x00, 0x02, 0x80, 0x18, 0xc0, 0x05, 0x70, 0x47, 0x80, 0x03, 0x00, 0x00, + 0x00, 0x21, 0x0a, 0x00, 0x00, 0x21, 0x04, 0xe0, 0x00, 0x21, 0x0a, 0x00, + 0xc1, 0x17, 0x04, 0xe0, 0x00, 0x22, 0x00, 0x23, 0x06, 0xe0, 0xc0, 0x46, + 0x00, 0x22, 0xcb, 0x17, 0x58, 0x40, 0x59, 0x40, 0xc0, 0x1a, 0x99, 0x41, + 0x30, 0xb5, 0x18, 0x4c, 0xa2, 0x1a, 0x00, 0x29, 0x03, 0xd1, 0x01, 0x00, + 0x10, 0xd0, 0x00, 0x20, 0x20, 0x3a, 0x4c, 0x15, 0x12, 0xd1, 0x04, 0xd2, + 0x01, 0x3a, 0x00, 0x18, 0x49, 0x41, 0x4c, 0x0d, 0xfa, 0xd3, 0x11, 0x4c, + 0xa2, 0x42, 0x04, 0xd2, 0x12, 0x05, 0x89, 0x18, 0xdb, 0x07, 0xc9, 0x18, + 0x30, 0xbd, 0xd2, 0x43, 0x52, 0x0d, 0x00, 0x20, 0x00, 0x21, 0xf5, 0xe7, + 0x03, 0xd4, 0x01, 0x3a, 0x00, 0x18, 0x49, 0x41, 0xfb, 0xd5, 0x0b, 0x32, + 0x44, 0x05, 0xc0, 0x0a, 0x4d, 0x05, 0x28, 0x43, 0xc9, 0x0a, 0x64, 0x00, + 0x03, 0xd0, 0x00, 0x24, 0x60, 0x41, 0x61, 0x41, 0xe1, 0xe7, 0xe0, 0xd3, + 0x44, 0x08, 0xf8, 0xe7, 0x32, 0x04, 0x00, 0x00, 0xfe, 0x07, 0x00, 0x00, + 0x0a, 0x0d, 0xcc, 0x0f, 0x53, 0x1e, 0x1b, 0x05, 0xc9, 0x1a, 0x52, 0x05, + 0x03, 0xd3, 0xc9, 0x43, 0x40, 0x42, 0x00, 0xd3, 0x01, 0x31, 0x52, 0x0d, + 0x03, 0xd0, 0x53, 0x1c, 0xdb, 0x0a, 0x07, 0xd0, 0x12, 0x1b, 0x00, 0x20, + 0x64, 0x00, 0x61, 0x1c, 0x89, 0x07, 0x89, 0x12, 0x80, 0x3a, 0x12, 0x03, + 0x01, 0x4b, 0xd2, 0x1a, 0x70, 0x47, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, + 0x51, 0x43, 0x43, 0x43, 0xc9, 0x18, 0x8c, 0x46, 0x11, 0x0c, 0x83, 0xb2, + 0x4b, 0x43, 0x10, 0xb4, 0x04, 0x0c, 0x61, 0x43, 0x92, 0xb2, 0x80, 0xb2, + 0x50, 0x43, 0x62, 0x43, 0x1c, 0x04, 0x1b, 0x0c, 0x00, 0x19, 0x10, 0xbc, + 0x59, 0x41, 0x13, 0x04, 0x12, 0x0c, 0xc0, 0x18, 0x51, 0x41, 0x61, 0x44, + 0x70, 0x47, 0x00, 0x00, 0x01, 0x48, 0x04, 0x21, 0x01, 0x4b, 0x18, 0x47, + 0x60, 0x05, 0x00, 0x20, 0xc9, 0x61, 0x00, 0x10, 0x01, 0x4b, 0x1b, 0x68, + 0x18, 0x47, 0x00, 0x00, 0x60, 0x05, 0x00, 0x20, 0x01, 0x4b, 0x5b, 0x68, + 0x18, 0x47, 0x00, 0x00, 0x60, 0x05, 0x00, 0x20, 0x10, 0xb5, 0x02, 0xf0, + 0x30, 0xfc, 0x10, 0xbd, 0x10, 0xb5, 0x02, 0xf0, 0x2c, 0xfc, 0x10, 0xbd, + 0x10, 0xb5, 0x02, 0xf0, 0x30, 0xfc, 0x10, 0xbd, 0x10, 0xb5, 0x02, 0xf0, + 0x2c, 0xfc, 0x10, 0xbd, 0xd0, 0x23, 0x01, 0x22, 0x1b, 0x06, 0x19, 0x6d, + 0x11, 0x42, 0x01, 0xd0, 0x98, 0x6d, 0x70, 0x47, 0x20, 0xbf, 0xf8, 0xe7, + 0x03, 0xbd, 0x10, 0xb5, 0x04, 0x00, 0xfe, 0xf7, 0xc1, 0xf8, 0xa0, 0x47, + 0x10, 0xbd, 0xd0, 0x23, 0x02, 0x22, 0x1b, 0x06, 0x19, 0x6d, 0x11, 0x42, + 0xfc, 0xd0, 0x58, 0x65, 0x40, 0xbf, 0x70, 0x47, 0x10, 0xb5, 0xff, 0xf7, + 0xe3, 0xff, 0x10, 0xbd, 0xf0, 0xb5, 0x04, 0x00, 0x89, 0xb0, 0x0f, 0x20, + 0x17, 0x00, 0x0e, 0x00, 0xfd, 0xf7, 0x52, 0xff, 0x00, 0x21, 0x01, 0x90, + 0x0f, 0x20, 0xfd, 0xf7, 0x69, 0xff, 0x00, 0x23, 0x01, 0x25, 0x05, 0x97, + 0xd0, 0x27, 0x07, 0x94, 0x1c, 0x00, 0x02, 0x93, 0x03, 0x93, 0x04, 0x95, + 0x06, 0x96, 0x3f, 0x06, 0xa3, 0x00, 0x02, 0xaa, 0xd6, 0x58, 0x00, 0x2e, + 0x03, 0xd1, 0x3b, 0x6d, 0x2b, 0x42, 0x12, 0xd1, 0x40, 0xbf, 0x30, 0x00, + 0xff, 0xf7, 0xcf, 0xff, 0xff, 0xf7, 0xbc, 0xff, 0x86, 0x42, 0x08, 0xd1, + 0x01, 0x34, 0x05, 0x2c, 0xec, 0xd9, 0x0f, 0x20, 0x01, 0x99, 0xfd, 0xf7, + 0x47, 0xff, 0x09, 0xb0, 0xf0, 0xbd, 0x00, 0x24, 0xe4, 0xe7, 0xbb, 0x6d, + 0xe7, 0xe7, 0x00, 0x00, 0x0b, 0x00, 0x03, 0x21, 0x8a, 0x43, 0x9a, 0x18, + 0x11, 0x00, 0x0c, 0x39, 0x10, 0xb5, 0x08, 0x60, 0x10, 0x00, 0x08, 0x38, + 0x03, 0x60, 0x04, 0x4b, 0x04, 0x3a, 0x13, 0x60, 0x03, 0x4b, 0x04, 0x48, + 0x9a, 0x68, 0xff, 0xf7, 0xb7, 0xff, 0x10, 0xbd, 0x3f, 0x75, 0x00, 0x10, + 0x00, 0xed, 0x00, 0xe0, 0x3d, 0x75, 0x00, 0x10, 0x05, 0x4b, 0x06, 0x49, + 0x10, 0xb5, 0x99, 0x42, 0x01, 0xd2, 0x01, 0x21, 0x49, 0x42, 0x80, 0x22, + 0x12, 0x01, 0xff, 0xf7, 0xdb, 0xff, 0x10, 0xbd, 0x00, 0x00, 0x04, 0x20, + 0x00, 0x08, 0x04, 0x20, 0x0b, 0x4a, 0x03, 0x00, 0x00, 0x2a, 0x0b, 0xd0, + 0x0a, 0x4a, 0x10, 0x78, 0x98, 0x42, 0x05, 0xd9, 0x18, 0x20, 0x09, 0x4a, + 0x43, 0x43, 0x10, 0x68, 0xc0, 0x18, 0x70, 0x47, 0x1b, 0x1a, 0xdb, 0xb2, + 0x00, 0x20, 0x01, 0x2b, 0xf9, 0xd8, 0x18, 0x30, 0x43, 0x43, 0x04, 0x48, + 0xf4, 0xe7, 0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, 0xd0, 0x1a, 0x00, 0x20, + 0xbc, 0x0e, 0x00, 0x20, 0xa4, 0x00, 0x01, 0x10, 0x70, 0xb5, 0x05, 0x00, + 0x00, 0x24, 0x20, 0x00, 0xff, 0xf7, 0xda, 0xff, 0x43, 0x68, 0x28, 0x00, + 0x98, 0x47, 0x0c, 0x4b, 0x01, 0x34, 0x1b, 0x78, 0xe4, 0xb2, 0x01, 0x33, + 0xa3, 0x42, 0xf2, 0xda, 0x09, 0x4c, 0x53, 0x22, 0x00, 0x21, 0x20, 0x00, + 0xff, 0xf7, 0x30, 0xff, 0x10, 0x22, 0xff, 0x21, 0xe0, 0x1c, 0xff, 0xf7, + 0x2b, 0xff, 0x20, 0x00, 0x20, 0x22, 0xff, 0x21, 0x13, 0x30, 0xff, 0xf7, + 0x25, 0xff, 0x70, 0xbd, 0xd0, 0x1a, 0x00, 0x20, 0xd1, 0x1a, 0x00, 0x20, + 0x70, 0xb5, 0x05, 0x00, 0x0c, 0x00, 0x16, 0x00, 0xc8, 0x68, 0x00, 0xf0, + 0x3b, 0xfd, 0x32, 0x00, 0x28, 0x00, 0x00, 0x21, 0xe3, 0x68, 0x98, 0x47, + 0x70, 0xbd, 0x10, 0xb5, 0x04, 0x00, 0xc0, 0x69, 0xef, 0xf3, 0x10, 0x83, + 0x72, 0xb6, 0x02, 0x68, 0x00, 0x2a, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, + 0x23, 0x62, 0x20, 0x00, 0x01, 0xf0, 0x3f, 0xfc, 0xe2, 0x69, 0x23, 0x6a, + 0xbf, 0xf3, 0x5f, 0x8f, 0x00, 0x21, 0x11, 0x60, 0x83, 0xf3, 0x10, 0x88, + 0x10, 0xbd, 0x00, 0x00, 0x02, 0x4b, 0x58, 0x78, 0x43, 0x1e, 0x98, 0x41, + 0xc0, 0xb2, 0x70, 0x47, 0xd1, 0x1a, 0x00, 0x20, 0x02, 0x4b, 0x18, 0x78, + 0x40, 0x07, 0xc0, 0x0f, 0x70, 0x47, 0xc0, 0x46, 0xd1, 0x1a, 0x00, 0x20, + 0x01, 0x4b, 0x18, 0x78, 0x70, 0x47, 0xc0, 0x46, 0x24, 0x1b, 0x00, 0x20, + 0xf8, 0xb5, 0x1c, 0x4e, 0x05, 0x00, 0x31, 0x78, 0x00, 0x29, 0x30, 0xd1, + 0x53, 0x22, 0x1a, 0x48, 0xff, 0xf7, 0xda, 0xfe, 0x19, 0x4c, 0x20, 0x00, + 0xfe, 0xf7, 0xec, 0xfc, 0x18, 0x4b, 0x1c, 0x60, 0x18, 0x4c, 0x20, 0x00, + 0x1c, 0x30, 0x01, 0xf0, 0xdb, 0xfd, 0x20, 0x00, 0x01, 0xf0, 0x40, 0xfc, + 0x15, 0x4b, 0x16, 0x4f, 0x1c, 0x60, 0x16, 0x4b, 0x00, 0x2b, 0x04, 0xd0, + 0x38, 0x00, 0x00, 0xe0, 0x00, 0xbf, 0x14, 0x4b, 0x18, 0x60, 0x00, 0x24, + 0x20, 0x00, 0xff, 0xf7, 0x57, 0xff, 0x03, 0x68, 0x98, 0x47, 0x3b, 0x78, + 0x01, 0x34, 0xe4, 0xb2, 0x01, 0x33, 0xa3, 0x42, 0xf4, 0xda, 0x28, 0x00, + 0x01, 0xf0, 0x82, 0xff, 0x28, 0x00, 0x01, 0xf0, 0x67, 0xff, 0x01, 0x23, + 0x33, 0x70, 0x01, 0x20, 0xf8, 0xbd, 0xc0, 0x46, 0x24, 0x1b, 0x00, 0x20, + 0xd1, 0x1a, 0x00, 0x20, 0xcc, 0x12, 0x00, 0x20, 0x14, 0x13, 0x00, 0x20, + 0x70, 0x05, 0x00, 0x20, 0x18, 0x13, 0x00, 0x20, 0xd0, 0x1a, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0xbc, 0x0e, 0x00, 0x20, 0x1f, 0xb5, 0x04, 0x00, + 0x40, 0x78, 0x02, 0x38, 0x03, 0x28, 0x18, 0xd8, 0x19, 0x4b, 0x1a, 0x78, + 0x08, 0xf0, 0x72, 0xfa, 0x02, 0x1a, 0x0f, 0x17, 0x01, 0x21, 0x8a, 0x43, + 0x1a, 0x70, 0x1a, 0x78, 0x49, 0x18, 0x8a, 0x43, 0x1a, 0x70, 0x00, 0x22, + 0x5a, 0x70, 0x04, 0x21, 0x1a, 0x78, 0x8a, 0x43, 0x04, 0xe0, 0xd2, 0x07, + 0x07, 0xd5, 0x04, 0x22, 0x19, 0x78, 0x0a, 0x43, 0x1a, 0x70, 0x21, 0x00, + 0x13, 0xe0, 0xd2, 0x07, 0xf1, 0xd4, 0x1f, 0xbd, 0x52, 0x07, 0xfc, 0xd5, + 0x04, 0x21, 0x1a, 0x78, 0x01, 0xa8, 0x8a, 0x43, 0x1a, 0x70, 0x00, 0x21, + 0x0c, 0x22, 0xff, 0xf7, 0x69, 0xfe, 0x6a, 0x46, 0x23, 0x78, 0x01, 0xa9, + 0x13, 0x71, 0x05, 0x23, 0x53, 0x71, 0x03, 0x4b, 0x18, 0x68, 0xff, 0xf7, + 0x4c, 0xff, 0xe8, 0xe7, 0xd1, 0x1a, 0x00, 0x20, 0x18, 0x13, 0x00, 0x20, + 0x7f, 0xb5, 0x06, 0x00, 0x0d, 0x00, 0x14, 0x00, 0x00, 0x21, 0x0c, 0x22, + 0x01, 0xa8, 0xff, 0xf7, 0x51, 0xfe, 0x6b, 0x46, 0x21, 0x00, 0x01, 0xa8, + 0x1e, 0x71, 0x5d, 0x71, 0xff, 0xf7, 0xb2, 0xff, 0x7f, 0xbd, 0xf0, 0xb5, + 0x85, 0xb0, 0x01, 0xac, 0x07, 0x00, 0x0e, 0x00, 0x15, 0x00, 0x00, 0x21, + 0x0c, 0x22, 0x20, 0x00, 0xff, 0xf7, 0x3e, 0xfe, 0x01, 0x23, 0x29, 0x00, + 0x20, 0x00, 0x27, 0x70, 0x63, 0x70, 0x26, 0x71, 0xff, 0xf7, 0x9e, 0xff, + 0x05, 0xb0, 0xf0, 0xbd, 0x1f, 0xb5, 0x14, 0x00, 0x6b, 0x46, 0x00, 0x22, + 0xda, 0x80, 0x6b, 0x46, 0x6a, 0x46, 0x18, 0x71, 0x06, 0x23, 0x02, 0xa8, + 0x53, 0x71, 0x08, 0x22, 0xff, 0xf7, 0x2c, 0xfe, 0x21, 0x00, 0x01, 0xa8, + 0xff, 0xf7, 0x8a, 0xff, 0x1f, 0xbd, 0xf0, 0xb5, 0x87, 0xb0, 0x03, 0xac, + 0x06, 0x00, 0x0d, 0x00, 0x00, 0x92, 0x01, 0x93, 0x08, 0x22, 0x0c, 0xab, + 0x00, 0x21, 0x20, 0x00, 0x1f, 0x78, 0xff, 0xf7, 0x13, 0xfe, 0x07, 0x23, + 0x63, 0x70, 0x00, 0x9b, 0x39, 0x00, 0x05, 0x93, 0x01, 0x9b, 0x20, 0x00, + 0x26, 0x70, 0x25, 0x71, 0x63, 0x71, 0xff, 0xf7, 0x6f, 0xff, 0x07, 0xb0, + 0xf0, 0xbd, 0x00, 0x00, 0x70, 0x23, 0x70, 0xb5, 0x8a, 0x78, 0x05, 0x00, + 0x0c, 0x00, 0x1a, 0x42, 0x01, 0xd0, 0x00, 0x20, 0x70, 0xbd, 0x06, 0x4b, + 0x20, 0x00, 0x99, 0x78, 0x01, 0xf0, 0x72, 0xf8, 0x00, 0x28, 0xf6, 0xd0, + 0x21, 0x00, 0x28, 0x00, 0x01, 0xf0, 0xfe, 0xfe, 0xf2, 0xe7, 0xc0, 0x46, + 0xd1, 0x1a, 0x00, 0x20, 0xf7, 0xb5, 0x06, 0x00, 0x0c, 0x00, 0x1f, 0x00, + 0x00, 0x25, 0x01, 0x92, 0x01, 0x9b, 0xab, 0x42, 0x01, 0xdc, 0x01, 0x20, + 0x03, 0xe0, 0x63, 0x78, 0x05, 0x2b, 0x01, 0xd0, 0x00, 0x20, 0xfe, 0xbd, + 0xe3, 0x78, 0x9b, 0x07, 0x9b, 0x0f, 0xbb, 0x42, 0xf8, 0xd1, 0x21, 0x00, + 0x30, 0x00, 0xff, 0xf7, 0xcf, 0xff, 0x00, 0x28, 0xf2, 0xd0, 0xa3, 0x78, + 0xda, 0x09, 0x01, 0x2a, 0x05, 0xd1, 0x09, 0x9a, 0x13, 0x70, 0x23, 0x78, + 0x01, 0x35, 0xe4, 0x18, 0xe0, 0xe7, 0x08, 0x9a, 0xf8, 0xe7, 0x00, 0x00, + 0xf8, 0xb5, 0x7f, 0x24, 0x0c, 0x40, 0x63, 0x00, 0x15, 0x4c, 0xc9, 0x09, + 0xe4, 0x18, 0x64, 0x18, 0x30, 0x34, 0xe3, 0x78, 0xdb, 0x07, 0xdd, 0x0f, + 0x00, 0x2b, 0x1e, 0xd1, 0xe3, 0x78, 0x5b, 0x07, 0xdf, 0x0f, 0x00, 0x2b, + 0x15, 0xdb, 0x01, 0x21, 0x0e, 0x4e, 0x49, 0x42, 0x30, 0x68, 0x08, 0xf0, + 0x7f, 0xf9, 0xe3, 0x78, 0xdb, 0x07, 0xdd, 0x0f, 0x00, 0x2b, 0x0c, 0xd1, + 0xe3, 0x78, 0x5b, 0x07, 0x04, 0xd4, 0x04, 0x23, 0x01, 0x25, 0xe2, 0x78, + 0x13, 0x43, 0xe3, 0x70, 0x30, 0x68, 0x08, 0xf0, 0x37, 0xf9, 0x28, 0x00, + 0xf8, 0xbd, 0x3d, 0x00, 0xf8, 0xe7, 0x00, 0x25, 0xf9, 0xe7, 0xc0, 0x46, + 0xd1, 0x1a, 0x00, 0x20, 0x14, 0x13, 0x00, 0x20, 0x70, 0xb5, 0x0d, 0x00, + 0x01, 0x21, 0x0f, 0x4c, 0x49, 0x42, 0x20, 0x68, 0x08, 0xf0, 0x5c, 0xf9, + 0x7f, 0x21, 0x29, 0x40, 0x4b, 0x00, 0x0c, 0x49, 0xed, 0x09, 0xc9, 0x18, + 0x49, 0x19, 0x30, 0x31, 0xcb, 0x78, 0x00, 0x25, 0xdb, 0x07, 0x08, 0xd4, + 0xcb, 0x78, 0x5b, 0x07, 0xdd, 0x0f, 0x00, 0x2b, 0x03, 0xda, 0x04, 0x22, + 0xcb, 0x78, 0x93, 0x43, 0xcb, 0x70, 0x20, 0x68, 0x08, 0xf0, 0x0c, 0xf9, + 0x28, 0x00, 0x70, 0xbd, 0x14, 0x13, 0x00, 0x20, 0xd1, 0x1a, 0x00, 0x20, + 0x70, 0xb5, 0x06, 0x00, 0x7f, 0x20, 0x0e, 0x4c, 0x08, 0x40, 0x40, 0x00, + 0xcd, 0x09, 0x24, 0x18, 0x64, 0x19, 0x30, 0x34, 0xe5, 0x78, 0x00, 0x20, + 0xed, 0x07, 0x0f, 0xd4, 0x01, 0x25, 0xe0, 0x78, 0x28, 0x43, 0xe0, 0x70, + 0x30, 0x00, 0x01, 0xf0, 0x77, 0xfe, 0x00, 0x28, 0x06, 0xd1, 0x04, 0x22, + 0xe3, 0x78, 0xab, 0x43, 0xe3, 0x70, 0xe3, 0x78, 0x93, 0x43, 0xe3, 0x70, + 0x70, 0xbd, 0xc0, 0x46, 0xd1, 0x1a, 0x00, 0x20, 0x7f, 0x23, 0x10, 0xb5, + 0x0b, 0x40, 0x0a, 0x4c, 0x5b, 0x00, 0xe4, 0x18, 0xca, 0x09, 0xa4, 0x18, + 0x30, 0x34, 0xe3, 0x78, 0x9b, 0x07, 0x09, 0xd4, 0x01, 0xf0, 0x6e, 0xfe, + 0x02, 0x23, 0xe2, 0x78, 0x13, 0x43, 0xe3, 0x70, 0x01, 0x23, 0xe2, 0x78, + 0x13, 0x43, 0xe3, 0x70, 0x10, 0xbd, 0xc0, 0x46, 0xd1, 0x1a, 0x00, 0x20, + 0x7f, 0x23, 0x10, 0xb5, 0x0b, 0x40, 0x0a, 0x4c, 0x5b, 0x00, 0xe4, 0x18, + 0xca, 0x09, 0xa4, 0x18, 0x30, 0x34, 0xe3, 0x78, 0x9b, 0x07, 0x09, 0xd5, + 0x01, 0xf0, 0x6e, 0xfe, 0x02, 0x22, 0xe3, 0x78, 0x93, 0x43, 0xe3, 0x70, + 0xe3, 0x78, 0x01, 0x3a, 0x93, 0x43, 0xe3, 0x70, 0x10, 0xbd, 0xc0, 0x46, + 0xd1, 0x1a, 0x00, 0x20, 0x7f, 0x22, 0xcb, 0x09, 0x0a, 0x40, 0x04, 0x49, + 0x52, 0x00, 0x89, 0x18, 0xc9, 0x18, 0x30, 0x31, 0xc8, 0x78, 0x80, 0x07, + 0xc0, 0x0f, 0x70, 0x47, 0xd1, 0x1a, 0x00, 0x20, 0xf0, 0xb5, 0x8b, 0xb0, + 0x00, 0xf0, 0x79, 0xff, 0x00, 0x28, 0x00, 0xd1, 0x95, 0xe2, 0xbf, 0x4b, + 0x1d, 0x68, 0xe9, 0x69, 0xef, 0xf3, 0x10, 0x83, 0x72, 0xb6, 0x0a, 0x68, + 0x00, 0x2a, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x07, 0xac, 0x2b, 0x62, + 0x21, 0x00, 0x28, 0x00, 0x01, 0xf0, 0xf5, 0xf9, 0xea, 0x69, 0x2b, 0x6a, + 0xbf, 0xf3, 0x5f, 0x8f, 0x00, 0x21, 0x11, 0x60, 0x83, 0xf3, 0x10, 0x88, + 0x88, 0x42, 0x00, 0xd1, 0x79, 0xe2, 0x60, 0x78, 0x01, 0x38, 0x07, 0x28, + 0xdf, 0xd8, 0x08, 0xf0, 0x91, 0xf8, 0x08, 0x00, 0x11, 0x00, 0x6b, 0x02, + 0x40, 0x02, 0x4f, 0x02, 0x1c, 0x00, 0x19, 0x02, 0x6d, 0x02, 0x20, 0x78, + 0xff, 0xf7, 0x8c, 0xfd, 0x00, 0xf0, 0xe8, 0xfa, 0x22, 0x79, 0xa8, 0x4b, + 0x9a, 0x70, 0xcc, 0xe7, 0x20, 0x78, 0xff, 0xf7, 0x83, 0xfd, 0x00, 0xf0, + 0xdf, 0xfa, 0xa5, 0x4b, 0x00, 0x2b, 0xc4, 0xd0, 0x00, 0xe0, 0x00, 0xbf, + 0xc1, 0xe7, 0x01, 0x20, 0xa0, 0x4d, 0x04, 0x21, 0x2b, 0x78, 0x27, 0x78, + 0x03, 0x43, 0x2b, 0x70, 0x2b, 0x00, 0x33, 0x33, 0x1a, 0x78, 0x60, 0x26, + 0x82, 0x43, 0x1a, 0x70, 0x1a, 0x78, 0x8a, 0x43, 0x1a, 0x70, 0x2b, 0x00, + 0x34, 0x33, 0x1a, 0x78, 0x82, 0x43, 0x1a, 0x70, 0x1a, 0x78, 0x00, 0x20, + 0x8a, 0x43, 0x1a, 0x70, 0x00, 0xf0, 0xc8, 0xfa, 0x23, 0x79, 0x1a, 0x00, + 0x32, 0x40, 0x00, 0x92, 0xb2, 0x42, 0x27, 0xd0, 0x40, 0x2a, 0x0c, 0xd1, + 0x91, 0x48, 0x00, 0x28, 0x22, 0xd0, 0x00, 0xf0, 0xbb, 0xfa, 0x00, 0x21, + 0x38, 0x00, 0x08, 0xaa, 0x00, 0xe0, 0x00, 0xbf, 0x00, 0x28, 0x92, 0xd1, + 0x18, 0xe0, 0xdb, 0x06, 0xdb, 0x0e, 0x01, 0x93, 0x01, 0x2b, 0x00, 0xd1, + 0x53, 0xe1, 0x02, 0x2b, 0x00, 0xd1, 0x78, 0xe1, 0x00, 0x2b, 0x0d, 0xd1, + 0x00, 0x9b, 0x20, 0x2b, 0x14, 0xd1, 0x23, 0x7a, 0x0f, 0x2b, 0x07, 0xd8, + 0xeb, 0x18, 0xd8, 0x78, 0xff, 0xf7, 0x16, 0xfd, 0x08, 0xaa, 0x01, 0x1e, + 0x00, 0xd0, 0x7f, 0xe1, 0x07, 0xac, 0x20, 0x78, 0x00, 0x21, 0x01, 0xf0, + 0xa7, 0xfd, 0x80, 0x21, 0x20, 0x78, 0x01, 0xf0, 0xa3, 0xfd, 0x6e, 0xe7, + 0x00, 0x9b, 0x00, 0x2b, 0xf2, 0xd1, 0x60, 0x79, 0x09, 0x28, 0xef, 0xd8, + 0x08, 0xf0, 0x42, 0xf8, 0x1f, 0x01, 0x17, 0x01, 0xee, 0xff, 0x0e, 0x01, + 0xee, 0xff, 0x0a, 0x00, 0xb1, 0x00, 0xee, 0xff, 0x16, 0x00, 0x1c, 0x00, + 0x08, 0xa8, 0x00, 0xf0, 0x81, 0xfa, 0x38, 0x00, 0xa1, 0x79, 0x01, 0xf0, + 0x13, 0xfd, 0x02, 0x23, 0x2a, 0x78, 0x13, 0x43, 0x2b, 0x70, 0x50, 0xe7, + 0x06, 0xaa, 0x6b, 0x78, 0x02, 0x32, 0x13, 0x70, 0x01, 0x23, 0x0d, 0xe1, + 0xa3, 0x79, 0x00, 0x93, 0x6b, 0x78, 0x00, 0x9a, 0x9a, 0x42, 0x35, 0xd0, + 0x6b, 0x78, 0x00, 0x2b, 0x07, 0xd0, 0x38, 0x00, 0x01, 0xf0, 0x5c, 0xfd, + 0xac, 0x78, 0x38, 0x00, 0xff, 0xf7, 0xf4, 0xfc, 0xac, 0x70, 0x00, 0x9b, + 0x00, 0x2b, 0x27, 0xd0, 0x58, 0x1e, 0xc0, 0xb2, 0xfd, 0xf7, 0x78, 0xf9, + 0x00, 0x28, 0xb7, 0xd0, 0x43, 0x78, 0x03, 0x93, 0x02, 0x2b, 0xb3, 0xd1, + 0x01, 0x21, 0x04, 0x00, 0xc2, 0x79, 0x09, 0x34, 0x93, 0x11, 0x52, 0x11, + 0x0b, 0x40, 0x0a, 0x40, 0x12, 0x01, 0x5b, 0x01, 0x13, 0x43, 0x2a, 0x78, + 0x2f, 0x31, 0x8a, 0x43, 0x13, 0x43, 0x2b, 0x70, 0xc3, 0x78, 0x82, 0x78, + 0x1b, 0x02, 0x13, 0x43, 0xc3, 0x18, 0x04, 0x93, 0x04, 0x9b, 0xa3, 0x42, + 0x0c, 0xd8, 0x4d, 0x4b, 0x00, 0x2b, 0x01, 0xd0, 0x00, 0xe0, 0x00, 0xbf, + 0x47, 0x4b, 0x00, 0x9a, 0x5a, 0x70, 0x38, 0x00, 0x08, 0xa9, 0x00, 0xf0, + 0xe3, 0xf9, 0x06, 0xe7, 0x01, 0x22, 0x63, 0x78, 0x01, 0x92, 0x0b, 0x2b, + 0x03, 0xd1, 0xe3, 0x78, 0x01, 0x93, 0x23, 0x78, 0xe4, 0x18, 0x63, 0x78, + 0x04, 0x2b, 0x81, 0xd1, 0x00, 0x26, 0x04, 0x9b, 0x1b, 0x1b, 0x9b, 0xb2, + 0x05, 0x93, 0x3f, 0x4b, 0x1b, 0x78, 0x01, 0x33, 0xb3, 0x42, 0x00, 0xda, + 0x76, 0xe7, 0x30, 0x00, 0xff, 0xf7, 0x86, 0xfc, 0x05, 0x00, 0x21, 0x00, + 0x38, 0x00, 0x05, 0x9a, 0xab, 0x68, 0x98, 0x47, 0x02, 0x90, 0x08, 0x28, + 0x2a, 0xd9, 0x05, 0x9b, 0x83, 0x42, 0x27, 0xd3, 0x01, 0x9b, 0x01, 0x2b, + 0x05, 0xd1, 0x34, 0x4b, 0xaa, 0x68, 0x9a, 0x42, 0x01, 0xd1, 0x03, 0x9b, + 0x01, 0x93, 0x00, 0x22, 0x2b, 0x48, 0x01, 0x9b, 0x9a, 0x42, 0x0d, 0xd1, + 0x33, 0x00, 0x21, 0x00, 0x02, 0x9a, 0x13, 0x30, 0x00, 0xf0, 0x78, 0xfe, + 0x02, 0x9b, 0xe4, 0x18, 0x29, 0x4b, 0x1b, 0x78, 0x01, 0x33, 0x9e, 0x42, + 0xae, 0xdd, 0x4b, 0xe7, 0xa3, 0x78, 0xd3, 0x18, 0xdb, 0xb2, 0xc3, 0x18, + 0xd9, 0x78, 0xff, 0x29, 0x00, 0xd0, 0x43, 0xe7, 0x01, 0x32, 0xde, 0x70, + 0xd2, 0xb2, 0xe2, 0xe7, 0x01, 0x36, 0xf6, 0xb2, 0xbf, 0xe7, 0xe3, 0x88, + 0x1a, 0x0a, 0x50, 0x1e, 0xdb, 0xb2, 0x0e, 0x28, 0x00, 0xd9, 0x35, 0xe7, + 0x07, 0xf0, 0x88, 0xff, 0x0f, 0x00, 0x24, 0x00, 0x44, 0x00, 0x34, 0xff, + 0x34, 0xff, 0x4d, 0x00, 0x24, 0x00, 0x34, 0xff, 0x34, 0xff, 0x34, 0xff, + 0x34, 0xff, 0x34, 0xff, 0x34, 0xff, 0x34, 0xff, 0x18, 0x00, 0xfc, 0xf7, + 0x5d, 0xff, 0x12, 0x23, 0x02, 0x00, 0x38, 0x00, 0x08, 0xa9, 0x00, 0xf0, + 0x83, 0xf9, 0xff, 0xe6, 0x10, 0x4b, 0x00, 0x2b, 0x00, 0xd1, 0x17, 0xe7, + 0x00, 0xe0, 0x00, 0xbf, 0x02, 0x00, 0xd3, 0x78, 0x91, 0x78, 0x1b, 0x02, + 0x0b, 0x43, 0xee, 0xe7, 0x02, 0x2a, 0x15, 0xd1, 0x18, 0x00, 0xfd, 0xf7, + 0xc9, 0xf8, 0x02, 0x1e, 0xf3, 0xd1, 0x07, 0xe7, 0x18, 0x13, 0x00, 0x20, + 0xd1, 0x1a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd0, 0x1a, 0x00, 0x20, 0x3d, 0x84, 0x00, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x84, 0x4a, 0x00, 0x2a, 0x00, 0xd1, 0xf3, 0xe6, + 0x18, 0x00, 0x00, 0xe0, 0x00, 0xbf, 0xe4, 0xe7, 0x18, 0x00, 0x21, 0x89, + 0xfd, 0xf7, 0x46, 0xfa, 0x02, 0x1e, 0x00, 0xd1, 0xe8, 0xe6, 0x03, 0x78, + 0xc5, 0xe7, 0x7d, 0x4b, 0x00, 0x2b, 0x00, 0xd1, 0xe2, 0xe6, 0x00, 0xe0, + 0x00, 0xbf, 0xf3, 0xe7, 0xe3, 0x88, 0x01, 0x2b, 0x00, 0xd0, 0xdb, 0xe6, + 0x2a, 0x78, 0x07, 0x33, 0x13, 0x43, 0x2b, 0x70, 0x43, 0xe7, 0xe3, 0x88, + 0x01, 0x2b, 0x00, 0xd0, 0xd2, 0xe6, 0x08, 0x22, 0x2b, 0x78, 0x93, 0x43, + 0xf5, 0xe7, 0x01, 0x21, 0x2b, 0x78, 0x06, 0xaa, 0x58, 0x09, 0x08, 0x40, + 0x99, 0x08, 0x02, 0x23, 0x19, 0x40, 0x02, 0x32, 0x01, 0x43, 0x11, 0x80, + 0x38, 0x00, 0x08, 0xa9, 0x00, 0xf0, 0x26, 0xf9, 0x37, 0xe6, 0x23, 0x7a, + 0x0f, 0x2b, 0x00, 0xd9, 0xba, 0xe6, 0xeb, 0x18, 0xd8, 0x78, 0xff, 0xf7, + 0xc9, 0xfb, 0x01, 0x1e, 0x00, 0xd1, 0xb3, 0xe6, 0x38, 0x00, 0x08, 0xaa, + 0xff, 0xf7, 0x08, 0xfc, 0x00, 0x28, 0x00, 0xd0, 0x25, 0xe6, 0x23, 0x79, + 0x1d, 0x00, 0x35, 0x40, 0x33, 0x42, 0x00, 0xd0, 0xa6, 0xe6, 0x63, 0x79, + 0x0a, 0x3b, 0x01, 0x2b, 0x00, 0xd9, 0xa1, 0xe6, 0x28, 0x00, 0x00, 0xf0, + 0x39, 0xf9, 0x63, 0x79, 0x0a, 0x2b, 0x00, 0xd0, 0x07, 0xe7, 0x06, 0xab, + 0x9a, 0x1c, 0x15, 0x70, 0xc2, 0xe6, 0x70, 0x23, 0x26, 0x7a, 0x1e, 0x42, + 0x00, 0xd0, 0x91, 0xe6, 0x0f, 0x33, 0x33, 0x40, 0x5b, 0x00, 0xf2, 0x09, + 0xeb, 0x18, 0x9b, 0x18, 0xd8, 0x7c, 0xff, 0xf7, 0x9b, 0xfb, 0x00, 0x9b, + 0x02, 0x90, 0x00, 0x2b, 0x08, 0xd0, 0x00, 0x28, 0x00, 0xd1, 0x81, 0xe6, + 0x01, 0x00, 0x08, 0xaa, 0x38, 0x00, 0xff, 0xf7, 0xd5, 0xfb, 0x5f, 0xe6, + 0x63, 0x79, 0x01, 0x99, 0x1a, 0x00, 0x8a, 0x43, 0x01, 0x2a, 0x0b, 0xd0, + 0x00, 0x2b, 0x00, 0xd0, 0x72, 0xe6, 0x31, 0x00, 0x38, 0x00, 0xff, 0xf7, + 0xd3, 0xfd, 0x06, 0xab, 0x9a, 0x1c, 0x10, 0x80, 0x01, 0x9b, 0xa5, 0xe7, + 0xe2, 0x88, 0x00, 0x2a, 0x05, 0xd1, 0x31, 0x00, 0x38, 0x00, 0x01, 0x2b, + 0x13, 0xd1, 0xff, 0xf7, 0xab, 0xfd, 0x02, 0x9b, 0x00, 0x2b, 0x00, 0xd1, + 0xd5, 0xe5, 0x19, 0x00, 0x08, 0xaa, 0x38, 0x00, 0xff, 0xf7, 0xb0, 0xfb, + 0x34, 0x35, 0x00, 0x20, 0x00, 0xf0, 0xee, 0xf8, 0x2b, 0x78, 0xdb, 0x07, + 0x00, 0xd5, 0xc8, 0xe5, 0xbb, 0xe6, 0xff, 0xf7, 0x7d, 0xfd, 0xea, 0xe7, + 0x7f, 0x20, 0x25, 0x79, 0x2f, 0x4b, 0x28, 0x40, 0x41, 0x00, 0xea, 0x09, + 0x5b, 0x18, 0x9b, 0x18, 0x1a, 0x00, 0x01, 0x26, 0x30, 0x32, 0xd1, 0x78, + 0xb1, 0x43, 0xd1, 0x70, 0xd1, 0x78, 0x03, 0x36, 0xb1, 0x43, 0xd1, 0x70, + 0x00, 0x28, 0x06, 0xd1, 0x29, 0x00, 0x62, 0x79, 0x20, 0x78, 0xa3, 0x68, + 0x00, 0xf0, 0xe0, 0xf8, 0xa9, 0xe5, 0xd8, 0x7c, 0xff, 0xf7, 0x40, 0xfb, + 0x03, 0x1e, 0x3a, 0xd0, 0x1e, 0x69, 0x29, 0x00, 0x62, 0x79, 0x20, 0x78, + 0xa3, 0x68, 0xb0, 0x47, 0x9d, 0xe5, 0x1d, 0x4b, 0x1a, 0x78, 0xd2, 0x07, + 0x00, 0xd4, 0x98, 0xe5, 0x1b, 0x4a, 0x00, 0x2a, 0x00, 0xd1, 0x94, 0xe5, + 0x18, 0x78, 0x00, 0x07, 0xc0, 0x0f, 0x00, 0xe0, 0x00, 0xbf, 0x8e, 0xe5, + 0x15, 0x4b, 0x1b, 0x78, 0xdb, 0x07, 0x00, 0xd4, 0x89, 0xe5, 0x15, 0x4b, + 0x00, 0x2b, 0x00, 0xd1, 0x85, 0xe5, 0x00, 0xe0, 0x00, 0xbf, 0x82, 0xe5, + 0x28, 0x00, 0xff, 0xf7, 0x19, 0xfb, 0x43, 0x69, 0x00, 0x2b, 0x01, 0xd0, + 0x20, 0x78, 0x98, 0x47, 0x01, 0x35, 0xed, 0xb2, 0x0d, 0x4b, 0x1b, 0x78, + 0x01, 0x33, 0xab, 0x42, 0xf0, 0xda, 0x72, 0xe5, 0x00, 0x25, 0xf7, 0xe7, + 0x63, 0x68, 0x00, 0x2b, 0x00, 0xd1, 0x6c, 0xe5, 0xa0, 0x68, 0x98, 0x47, + 0x69, 0xe5, 0x0b, 0xb0, 0xf0, 0xbd, 0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd1, 0x1a, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xd0, 0x1a, 0x00, 0x20, 0x70, 0xb5, 0x13, 0x4b, + 0x06, 0x00, 0xd9, 0x89, 0x98, 0x89, 0x42, 0x1a, 0x15, 0x1c, 0x92, 0xb2, + 0x40, 0x2a, 0x00, 0xd9, 0x40, 0x25, 0x1a, 0x78, 0xad, 0xb2, 0x7f, 0x2a, + 0x0e, 0xd9, 0x88, 0x42, 0x11, 0xd0, 0x0c, 0x4c, 0x2a, 0x00, 0x99, 0x68, + 0x20, 0x00, 0xff, 0xf7, 0x49, 0xfa, 0x80, 0x21, 0x22, 0x00, 0x2b, 0x00, + 0x30, 0x00, 0xff, 0xf7, 0xd3, 0xfc, 0x70, 0xbd, 0x88, 0x42, 0x04, 0xd1, + 0x00, 0x21, 0x00, 0x22, 0xf5, 0xe7, 0x80, 0x21, 0xfb, 0xe7, 0x00, 0x21, + 0x01, 0x4a, 0xf0, 0xe7, 0x98, 0x11, 0x00, 0x20, 0xd4, 0x12, 0x00, 0x20, + 0x49, 0xb2, 0xc9, 0x43, 0x00, 0x23, 0x10, 0xb5, 0xc9, 0x0f, 0x1a, 0x00, + 0xc9, 0x01, 0xff, 0xf7, 0xbb, 0xfc, 0x10, 0xbd, 0x70, 0xb5, 0x07, 0x4e, + 0x05, 0x00, 0x08, 0x22, 0x30, 0x00, 0x0c, 0x00, 0xff, 0xf7, 0x22, 0xfa, + 0x00, 0x23, 0x28, 0x00, 0xf3, 0x60, 0x21, 0x78, 0xb3, 0x60, 0xff, 0xf7, + 0xe7, 0xff, 0x70, 0xbd, 0x98, 0x11, 0x00, 0x20, 0xf7, 0xb5, 0x13, 0x4f, + 0x15, 0x00, 0x06, 0x00, 0x08, 0x22, 0x38, 0x00, 0x0c, 0x00, 0x01, 0x93, + 0xff, 0xf7, 0x0e, 0xfa, 0x00, 0x23, 0xbd, 0x60, 0xfb, 0x81, 0xe3, 0x79, + 0xa2, 0x79, 0x1b, 0x02, 0x01, 0x99, 0x13, 0x43, 0x1a, 0x1c, 0x8b, 0x42, + 0x01, 0xd9, 0x6a, 0x46, 0x92, 0x88, 0x91, 0xb2, 0xba, 0x81, 0x00, 0x2b, + 0x07, 0xd0, 0x00, 0x29, 0x01, 0xd0, 0x28, 0x1e, 0x02, 0xd0, 0x30, 0x00, + 0xff, 0xf7, 0x96, 0xff, 0xfe, 0xbd, 0x30, 0x00, 0x21, 0x78, 0xff, 0xf7, + 0xbd, 0xff, 0xf9, 0xe7, 0x98, 0x11, 0x00, 0x20, 0x10, 0xb5, 0x14, 0x22, + 0x00, 0x21, 0x02, 0x48, 0xff, 0xf7, 0xe2, 0xf9, 0x10, 0xbd, 0xc0, 0x46, + 0x98, 0x11, 0x00, 0x20, 0x01, 0x4b, 0x18, 0x61, 0x70, 0x47, 0xc0, 0x46, + 0x98, 0x11, 0x00, 0x20, 0x10, 0xb5, 0x05, 0x4c, 0x01, 0x00, 0x08, 0x22, + 0x20, 0x00, 0xff, 0xf7, 0xd7, 0xf9, 0x00, 0x23, 0xa3, 0x60, 0xe3, 0x60, + 0x10, 0xbd, 0xc0, 0x46, 0x98, 0x11, 0x00, 0x20, 0x70, 0xb5, 0x25, 0x4c, + 0x1e, 0x00, 0x23, 0x78, 0x05, 0x00, 0xda, 0x09, 0xc9, 0x09, 0x8a, 0x42, + 0x13, 0xd0, 0x00, 0x20, 0x86, 0x42, 0x2c, 0xd1, 0x20, 0x4b, 0x83, 0x42, + 0x03, 0xd0, 0x21, 0x00, 0x28, 0x00, 0x01, 0xf0, 0xb9, 0xfa, 0x23, 0x69, + 0x01, 0x20, 0x00, 0x2b, 0x21, 0xd0, 0x22, 0x00, 0x02, 0x21, 0x28, 0x00, + 0x98, 0x47, 0x01, 0x20, 0x1b, 0xe0, 0x7f, 0x2b, 0x06, 0xd8, 0xa3, 0x68, + 0x18, 0x1e, 0x16, 0xd0, 0x32, 0x00, 0x16, 0x49, 0xff, 0xf7, 0xaa, 0xf9, + 0xa2, 0x68, 0xe3, 0x89, 0x92, 0x19, 0x9b, 0x19, 0xa2, 0x60, 0xe2, 0x88, + 0x9b, 0xb2, 0xe3, 0x81, 0x9a, 0x42, 0x01, 0xd0, 0x3f, 0x2e, 0x15, 0xd8, + 0x23, 0x69, 0x00, 0x2b, 0x04, 0xd1, 0x28, 0x00, 0x21, 0x78, 0xff, 0xf7, + 0x63, 0xff, 0x70, 0xbd, 0x01, 0x21, 0x22, 0x00, 0x28, 0x00, 0x98, 0x47, + 0x01, 0x1e, 0xf4, 0xd1, 0x28, 0x00, 0x01, 0xf0, 0xbb, 0xfa, 0x80, 0x21, + 0x28, 0x00, 0x01, 0xf0, 0xb7, 0xfa, 0xd2, 0xe7, 0x28, 0x00, 0xff, 0xf7, + 0x25, 0xff, 0xec, 0xe7, 0x98, 0x11, 0x00, 0x20, 0xf5, 0x96, 0x00, 0x10, + 0xd4, 0x12, 0x00, 0x20, 0x70, 0xb5, 0x05, 0x00, 0x10, 0x35, 0x04, 0x00, + 0x28, 0x00, 0x00, 0xf0, 0x6a, 0xfe, 0x3f, 0x28, 0x12, 0xd9, 0x00, 0x20, + 0xe1, 0x78, 0xff, 0xf7, 0xa7, 0xfb, 0x00, 0x28, 0x0c, 0xd0, 0x28, 0x00, + 0x00, 0xf0, 0x5f, 0xfe, 0xe1, 0x78, 0x3f, 0x28, 0x07, 0xd9, 0x96, 0x23, + 0x9b, 0x00, 0xe2, 0x18, 0x00, 0x20, 0x40, 0x23, 0xff, 0xf7, 0xf2, 0xfb, + 0x70, 0xbd, 0x00, 0x20, 0xff, 0xf7, 0xc8, 0xfb, 0xfa, 0xe7, 0x00, 0x00, + 0x10, 0xb5, 0x04, 0x00, 0xff, 0xf7, 0x58, 0xfa, 0x00, 0x28, 0x01, 0xd1, + 0x00, 0x20, 0x10, 0xbd, 0xff, 0xf7, 0x5a, 0xfa, 0x00, 0x28, 0xf9, 0xd1, + 0xb6, 0x20, 0x01, 0x23, 0x80, 0x00, 0x44, 0x43, 0x02, 0x48, 0x00, 0x19, + 0x00, 0x79, 0x18, 0x40, 0xf1, 0xe7, 0xc0, 0x46, 0xc0, 0x0e, 0x00, 0x20, + 0xb6, 0x23, 0x9b, 0x00, 0x58, 0x43, 0x10, 0xb5, 0x02, 0x4b, 0x10, 0x30, + 0xc0, 0x18, 0x00, 0xf0, 0x16, 0xfe, 0x10, 0xbd, 0xc0, 0x0e, 0x00, 0x20, + 0x70, 0xb5, 0xb6, 0x24, 0xa4, 0x00, 0x44, 0x43, 0x20, 0x00, 0x06, 0x4e, + 0x10, 0x30, 0x92, 0xb2, 0x80, 0x19, 0x00, 0xf0, 0x49, 0xfe, 0x05, 0x00, + 0xa0, 0x19, 0xff, 0xf7, 0xab, 0xff, 0x28, 0x00, 0x70, 0xbd, 0xc0, 0x46, + 0xc0, 0x0e, 0x00, 0x20, 0xb6, 0x23, 0x9b, 0x00, 0x58, 0x43, 0x10, 0xb5, + 0x02, 0x4b, 0x10, 0x30, 0xc0, 0x18, 0x00, 0xf0, 0x3c, 0xfe, 0x10, 0xbd, + 0xc0, 0x0e, 0x00, 0x20, 0xf7, 0xb5, 0x04, 0x00, 0xff, 0xf7, 0x14, 0xfa, + 0x00, 0x28, 0x01, 0xd1, 0x00, 0x20, 0xfe, 0xbd, 0xff, 0xf7, 0x16, 0xfa, + 0x05, 0x1e, 0xf9, 0xd1, 0xb6, 0x20, 0x80, 0x00, 0x44, 0x43, 0x26, 0x00, + 0x14, 0x4f, 0x2c, 0x36, 0xf6, 0x19, 0x30, 0x00, 0x00, 0xf0, 0xdd, 0xfd, + 0x00, 0x28, 0xed, 0xd0, 0x3b, 0x19, 0x28, 0x00, 0x99, 0x78, 0x01, 0x93, + 0xff, 0xf7, 0x30, 0xfb, 0x00, 0x28, 0xe5, 0xd0, 0xa6, 0x23, 0x9b, 0x00, + 0xe4, 0x18, 0xe7, 0x19, 0x39, 0x00, 0x40, 0x22, 0x30, 0x00, 0x00, 0xf0, + 0x0b, 0xfe, 0x01, 0x9b, 0x04, 0x00, 0x99, 0x78, 0x00, 0x28, 0x08, 0xd0, + 0x03, 0x00, 0x3a, 0x00, 0x28, 0x00, 0xff, 0xf7, 0x75, 0xfb, 0x00, 0x28, + 0xd0, 0xd0, 0x20, 0x00, 0xcf, 0xe7, 0xff, 0xf7, 0x49, 0xfb, 0xfa, 0xe7, + 0xc0, 0x0e, 0x00, 0x20, 0x70, 0xb5, 0xb6, 0x24, 0xa4, 0x00, 0x44, 0x43, + 0x09, 0x4b, 0x2c, 0x34, 0xe4, 0x18, 0x05, 0x00, 0x92, 0xb2, 0x20, 0x00, + 0x00, 0xf0, 0x35, 0xfe, 0x06, 0x00, 0x20, 0x00, 0x00, 0xf0, 0xa7, 0xfd, + 0x3f, 0x28, 0x02, 0xd9, 0x28, 0x00, 0xff, 0xf7, 0xaf, 0xff, 0x30, 0x00, + 0x70, 0xbd, 0xc0, 0x46, 0xc0, 0x0e, 0x00, 0x20, 0xb6, 0x23, 0x9b, 0x00, + 0x58, 0x43, 0x10, 0xb5, 0x02, 0x4b, 0x2c, 0x30, 0xc0, 0x18, 0x00, 0xf0, + 0xac, 0xfd, 0x10, 0xbd, 0xc0, 0x0e, 0x00, 0x20, 0xf7, 0xb5, 0xb6, 0x22, + 0x15, 0x4c, 0x00, 0x21, 0x20, 0x00, 0x92, 0x00, 0xff, 0xf7, 0xa8, 0xf8, + 0xff, 0x23, 0x63, 0x71, 0x12, 0x4b, 0x80, 0x27, 0x00, 0x26, 0x01, 0x25, + 0xe3, 0x80, 0x08, 0x23, 0x7f, 0x00, 0x3a, 0x00, 0x25, 0x81, 0x23, 0x73, + 0x0e, 0x49, 0x2b, 0x00, 0x00, 0x96, 0x0e, 0x48, 0x00, 0xf0, 0x4e, 0xfd, + 0x2b, 0x00, 0x3a, 0x00, 0x0c, 0x49, 0x00, 0x95, 0x0c, 0x48, 0x00, 0xf0, + 0x47, 0xfd, 0x0c, 0x4d, 0x28, 0x00, 0xfd, 0xf7, 0xa1, 0xfe, 0xa5, 0x62, + 0x0a, 0x4d, 0x66, 0x62, 0x28, 0x00, 0xfd, 0xf7, 0x9b, 0xfe, 0x25, 0x64, + 0x66, 0x64, 0xf7, 0xbd, 0xc0, 0x0e, 0x00, 0x20, 0x00, 0xc2, 0xff, 0xff, + 0x08, 0x0f, 0x00, 0x20, 0xd0, 0x0e, 0x00, 0x20, 0x08, 0x10, 0x00, 0x20, + 0xec, 0x0e, 0x00, 0x20, 0x08, 0x11, 0x00, 0x20, 0x10, 0x11, 0x00, 0x20, + 0x10, 0xb5, 0x05, 0x22, 0x00, 0x21, 0x07, 0x48, 0xff, 0xf7, 0x6c, 0xf8, + 0x06, 0x48, 0x00, 0xf0, 0xdd, 0xfd, 0x06, 0x4c, 0x20, 0x00, 0x00, 0xf0, + 0xd9, 0xfd, 0x01, 0x21, 0x20, 0x00, 0x00, 0xf0, 0xef, 0xfd, 0x10, 0xbd, + 0xc0, 0x0e, 0x00, 0x20, 0xd0, 0x0e, 0x00, 0x20, 0xec, 0x0e, 0x00, 0x20, + 0xf0, 0xb5, 0x4b, 0x79, 0x07, 0x00, 0x85, 0xb0, 0x02, 0x2b, 0x03, 0xd0, + 0x00, 0x25, 0x28, 0x00, 0x05, 0xb0, 0xf0, 0xbd, 0x8b, 0x79, 0x02, 0x2b, + 0xf8, 0xd1, 0x1f, 0x4e, 0xb3, 0x78, 0x00, 0x2b, 0xf4, 0xd1, 0x8b, 0x78, + 0x09, 0x25, 0x33, 0x70, 0x0c, 0x78, 0x0c, 0x19, 0x03, 0xe0, 0x23, 0x78, + 0xed, 0x18, 0xad, 0xb2, 0xe4, 0x18, 0x63, 0x78, 0x24, 0x2b, 0x1d, 0xd1, + 0x95, 0x42, 0xf6, 0xd9, 0x63, 0x78, 0x04, 0x2b, 0x14, 0xd1, 0x63, 0x79, + 0x0a, 0x2b, 0x11, 0xd1, 0x23, 0x78, 0x38, 0x00, 0x03, 0x93, 0xe1, 0x18, + 0x11, 0x4b, 0x01, 0x93, 0x11, 0x4b, 0x00, 0x93, 0x02, 0x23, 0x1a, 0x00, + 0xff, 0xf7, 0x3c, 0xfa, 0x00, 0x28, 0xd1, 0xd0, 0x03, 0x9b, 0x0e, 0x35, + 0xed, 0x18, 0xad, 0xb2, 0x30, 0x00, 0xff, 0xf7, 0xa7, 0xfe, 0xca, 0xe7, + 0x05, 0x2b, 0xe1, 0xd1, 0x21, 0x00, 0x38, 0x00, 0xff, 0xf7, 0x14, 0xfa, + 0x00, 0x28, 0xc1, 0xd0, 0xa3, 0x78, 0x73, 0x70, 0x23, 0x78, 0xed, 0x18, + 0xad, 0xb2, 0xe4, 0x18, 0xd4, 0xe7, 0xc0, 0x46, 0xc0, 0x0e, 0x00, 0x20, + 0xc2, 0x0e, 0x00, 0x20, 0xc3, 0x0e, 0x00, 0x20, 0xf8, 0xb5, 0x05, 0x00, + 0x60, 0x20, 0x0b, 0x00, 0x11, 0x00, 0x12, 0x78, 0x00, 0x24, 0x02, 0x40, + 0x20, 0x2a, 0x43, 0xd1, 0x2a, 0x4f, 0x4a, 0x79, 0x0e, 0x79, 0x38, 0x78, + 0x12, 0x02, 0x32, 0x43, 0x90, 0x42, 0x3b, 0xd1, 0x48, 0x78, 0x20, 0x38, + 0x03, 0x28, 0x37, 0xd8, 0x07, 0xf0, 0xd4, 0xfb, 0x02, 0x15, 0x18, 0x38, + 0x00, 0x2b, 0x06, 0xd1, 0x07, 0x23, 0x28, 0x00, 0x21, 0x4a, 0xff, 0xf7, + 0xd5, 0xfd, 0x01, 0x24, 0x2a, 0xe0, 0x02, 0x2b, 0xfb, 0xd1, 0x1f, 0x4b, + 0x00, 0x2b, 0xf8, 0xd0, 0x00, 0x20, 0x1c, 0x49, 0xfc, 0xf7, 0x22, 0xf8, + 0xf3, 0xe7, 0x00, 0x2b, 0xf1, 0xd1, 0xeb, 0xe7, 0x00, 0x2b, 0x03, 0xd1, + 0x28, 0x00, 0xff, 0xf7, 0xaf, 0xfd, 0xea, 0xe7, 0x02, 0x2b, 0xe8, 0xd1, + 0x01, 0x24, 0xcd, 0x78, 0x8a, 0x78, 0x21, 0x00, 0x2d, 0x02, 0x15, 0x43, + 0x2e, 0x00, 0x13, 0x48, 0x3d, 0x71, 0xa9, 0x43, 0x00, 0xf0, 0x52, 0xfd, + 0x11, 0x4b, 0x26, 0x40, 0x00, 0x2b, 0xd8, 0xd0, 0x6a, 0x08, 0x31, 0x00, + 0x00, 0x20, 0x22, 0x40, 0xfb, 0xf7, 0xf8, 0xff, 0x20, 0x00, 0xf8, 0xbd, + 0x00, 0x2b, 0xdf, 0xd0, 0x02, 0x2b, 0xcc, 0xd1, 0x0a, 0x4b, 0x00, 0x2b, + 0xc9, 0xd0, 0x8b, 0x78, 0xc9, 0x78, 0x00, 0x20, 0x09, 0x02, 0x19, 0x43, + 0x00, 0xe0, 0x00, 0xbf, 0xc1, 0xe7, 0xc0, 0x46, 0xc0, 0x0e, 0x00, 0x20, + 0xc6, 0x0e, 0x00, 0x20, 0x7d, 0x45, 0x00, 0x10, 0xec, 0x0e, 0x00, 0x20, + 0x6d, 0x45, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0xf7, 0xb5, 0x31, 0x4c, + 0x01, 0x90, 0x00, 0x91, 0x1d, 0x00, 0xe3, 0x78, 0x8b, 0x42, 0x05, 0xd0, + 0xa3, 0x78, 0x8b, 0x42, 0x11, 0xd0, 0x00, 0x25, 0x28, 0x00, 0xfe, 0xbd, + 0x2b, 0x4f, 0x2c, 0x49, 0x38, 0x00, 0xaa, 0xb2, 0x00, 0xf0, 0xf3, 0xfc, + 0x2a, 0x4b, 0x00, 0x2b, 0x0b, 0xd1, 0x2a, 0x4b, 0x00, 0x2b, 0x1d, 0xd1, + 0x20, 0x00, 0xff, 0xf7, 0x07, 0xfe, 0xa3, 0x78, 0x00, 0x9a, 0x93, 0x42, + 0x1e, 0xd0, 0x01, 0x25, 0xe8, 0xe7, 0x63, 0x79, 0x00, 0x26, 0xff, 0x2b, + 0xef, 0xd0, 0xae, 0x42, 0xed, 0xd0, 0x1f, 0x4b, 0x62, 0x79, 0x9b, 0x5d, + 0x9a, 0x42, 0x07, 0xd1, 0x38, 0x00, 0x00, 0xf0, 0x5c, 0xfc, 0x00, 0x28, + 0x02, 0xd1, 0x61, 0x79, 0x00, 0xe0, 0x00, 0xbf, 0x01, 0x36, 0xee, 0xe7, + 0x38, 0x00, 0x00, 0xf0, 0x52, 0xfc, 0x00, 0x28, 0xdc, 0xd1, 0x00, 0xe0, + 0x00, 0xbf, 0xd9, 0xe7, 0x16, 0x4b, 0x00, 0x2b, 0x02, 0xd0, 0x00, 0x20, + 0x00, 0xe0, 0x00, 0xbf, 0x00, 0x20, 0xff, 0xf7, 0x41, 0xfe, 0x00, 0x28, + 0xd5, 0xd1, 0x12, 0x48, 0x00, 0xf0, 0x2f, 0xfc, 0x00, 0x28, 0xd0, 0xd1, + 0x00, 0x2d, 0xce, 0xd0, 0x3f, 0x23, 0x2e, 0x00, 0x1e, 0x40, 0x1d, 0x42, + 0xc9, 0xd1, 0xa1, 0x78, 0x01, 0x98, 0xff, 0xf7, 0x7d, 0xf9, 0x05, 0x1e, + 0xc3, 0xd0, 0x33, 0x00, 0x32, 0x00, 0xa1, 0x78, 0x01, 0x98, 0xff, 0xf7, + 0xcf, 0xf9, 0xa7, 0xe7, 0xc0, 0x0e, 0x00, 0x20, 0xd0, 0x0e, 0x00, 0x20, + 0x18, 0x11, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xec, 0x0e, 0x00, 0x20, 0x8c, 0x22, 0x10, 0xb5, + 0x00, 0x21, 0x02, 0x48, 0x52, 0x00, 0xfe, 0xf7, 0x23, 0xff, 0x10, 0xbd, + 0xac, 0x11, 0x00, 0x20, 0x10, 0xb5, 0x00, 0x20, 0xff, 0xf7, 0xf2, 0xff, + 0x10, 0xbd, 0x00, 0x00, 0xf0, 0xb5, 0x85, 0xb0, 0x03, 0x90, 0x13, 0x00, + 0x4a, 0x79, 0x0d, 0x00, 0x03, 0x2a, 0x04, 0xd0, 0x00, 0x23, 0x02, 0x93, + 0x02, 0x98, 0x05, 0xb0, 0xf0, 0xbd, 0x0a, 0x79, 0x07, 0x21, 0x51, 0x43, + 0x12, 0x31, 0x02, 0x91, 0x99, 0x42, 0xf3, 0xd8, 0x21, 0x4b, 0x5f, 0x78, + 0x00, 0x2f, 0x05, 0xd0, 0x19, 0x00, 0x8d, 0x31, 0x09, 0x78, 0x00, 0x29, + 0xea, 0xd1, 0x01, 0x27, 0x8c, 0x24, 0x7c, 0x43, 0x1e, 0x19, 0x30, 0x00, + 0x29, 0x78, 0x88, 0x30, 0x69, 0x18, 0x01, 0x60, 0x48, 0x78, 0x21, 0x28, + 0xde, 0xd1, 0x08, 0x78, 0x09, 0x18, 0x60, 0x1c, 0x18, 0x18, 0x01, 0x90, + 0xa0, 0x1c, 0x1b, 0x18, 0x00, 0x93, 0x03, 0x98, 0x03, 0x23, 0xff, 0xf7, + 0xf9, 0xf8, 0x00, 0x28, 0xd0, 0xd0, 0xab, 0x79, 0x01, 0x2b, 0x01, 0xd1, + 0xeb, 0x79, 0xf3, 0x70, 0x8c, 0x23, 0x01, 0x22, 0x7b, 0x43, 0x0c, 0x4e, + 0xa0, 0x1d, 0xf7, 0x18, 0x3a, 0x71, 0xaa, 0x78, 0x80, 0x19, 0x9a, 0x55, + 0x3b, 0x00, 0x88, 0x33, 0x19, 0x68, 0x02, 0x22, 0x07, 0x31, 0xfe, 0xf7, + 0xd3, 0xfe, 0xb9, 0x78, 0x00, 0x29, 0xb9, 0xd0, 0x22, 0x00, 0x48, 0x32, + 0x40, 0x23, 0x03, 0x98, 0x92, 0x19, 0xff, 0xf7, 0x59, 0xf9, 0xb1, 0xe7, + 0xac, 0x11, 0x00, 0x20, 0xf0, 0xb5, 0x1f, 0x26, 0x13, 0x78, 0x07, 0x00, + 0x14, 0x00, 0x85, 0xb0, 0x1e, 0x40, 0x01, 0x2e, 0x01, 0xd0, 0x00, 0x20, + 0x26, 0xe0, 0x70, 0x4d, 0x12, 0x79, 0x28, 0x78, 0x90, 0x42, 0x0d, 0xd0, + 0x28, 0x00, 0x8c, 0x30, 0x00, 0x78, 0x90, 0x42, 0xf3, 0xd1, 0x60, 0x22, + 0x18, 0x00, 0x10, 0x40, 0x13, 0x42, 0x28, 0xd1, 0x00, 0x29, 0x03, 0xd0, + 0x01, 0x20, 0x13, 0xe0, 0x00, 0x26, 0xf4, 0xe7, 0x63, 0x78, 0x06, 0x2b, + 0xe5, 0xd1, 0xe3, 0x78, 0x21, 0x2b, 0x0d, 0xd1, 0x8c, 0x22, 0x56, 0x43, + 0xad, 0x19, 0x88, 0x35, 0x2a, 0x68, 0x00, 0x2a, 0xdb, 0xd0, 0x21, 0x00, + 0x38, 0x00, 0x13, 0x78, 0xff, 0xf7, 0x7c, 0xfc, 0x05, 0xb0, 0xf0, 0xbd, + 0x22, 0x2b, 0xd2, 0xd1, 0x30, 0x00, 0xfc, 0xf7, 0xc7, 0xfb, 0x8c, 0x23, + 0x02, 0x00, 0x5e, 0x43, 0xad, 0x19, 0xeb, 0x88, 0x21, 0x00, 0x38, 0x00, + 0xff, 0xf7, 0x6c, 0xfc, 0xd8, 0xe7, 0x20, 0x28, 0xc3, 0xd1, 0x60, 0x78, + 0x01, 0x38, 0x0a, 0x28, 0xbf, 0xd8, 0x07, 0xf0, 0x51, 0xfa, 0x0b, 0x00, + 0x7f, 0x00, 0x88, 0x00, 0xbe, 0xff, 0xbe, 0xff, 0xbe, 0xff, 0xbe, 0xff, + 0xbe, 0xff, 0x3a, 0x00, 0x69, 0x00, 0x8f, 0x00, 0x00, 0x29, 0xc3, 0xd1, + 0xe3, 0x78, 0x03, 0x93, 0x8c, 0x23, 0x73, 0x43, 0x08, 0x33, 0xed, 0x18, + 0xe3, 0x79, 0xa0, 0x79, 0x1b, 0x02, 0x03, 0x43, 0xa1, 0x78, 0x18, 0x1c, + 0x40, 0x2b, 0x00, 0xd9, 0x40, 0x20, 0xac, 0x46, 0x80, 0xb2, 0x02, 0x91, + 0x00, 0x29, 0x0a, 0xd0, 0x00, 0x22, 0x02, 0x92, 0x01, 0x2b, 0x06, 0xd9, + 0x6b, 0x1c, 0x9c, 0x46, 0x01, 0x23, 0x01, 0x38, 0x29, 0x70, 0x80, 0xb2, + 0x02, 0x93, 0x63, 0x46, 0x03, 0x9a, 0x00, 0x90, 0x30, 0x00, 0xfc, 0xf7, + 0x97, 0xfd, 0x02, 0x9b, 0x2a, 0x00, 0x18, 0x18, 0x83, 0xb2, 0x00, 0x2b, + 0x00, 0xd1, 0x84, 0xe7, 0xb8, 0xe7, 0x00, 0x29, 0x0b, 0xd1, 0xe3, 0x79, + 0xa2, 0x79, 0x1b, 0x02, 0x13, 0x43, 0x40, 0x2b, 0x00, 0xd9, 0x7a, 0xe7, + 0x8c, 0x22, 0x72, 0x43, 0x48, 0x32, 0xaa, 0x18, 0xaa, 0xe7, 0x02, 0x29, + 0x00, 0xd0, 0x85, 0xe7, 0x8c, 0x23, 0x73, 0x43, 0xa0, 0x79, 0xe2, 0x78, + 0xa1, 0x78, 0xe4, 0x79, 0x48, 0x33, 0x24, 0x02, 0x04, 0x43, 0xeb, 0x18, + 0x20, 0x1c, 0x40, 0x2c, 0x00, 0xd9, 0x40, 0x20, 0x80, 0xb2, 0x00, 0x29, + 0x07, 0xd0, 0x01, 0x2c, 0x05, 0xd9, 0x1c, 0x78, 0x8c, 0x42, 0x02, 0xd1, + 0x01, 0x38, 0x01, 0x33, 0x80, 0xb2, 0x00, 0x90, 0x30, 0x00, 0xfc, 0xf7, + 0x63, 0xfd, 0x67, 0xe7, 0x00, 0x29, 0x00, 0xd0, 0x64, 0xe7, 0x8c, 0x22, + 0x72, 0x43, 0xe1, 0x78, 0x19, 0x4b, 0xad, 0x18, 0x69, 0x71, 0x00, 0x2b, + 0x05, 0xd0, 0x30, 0x00, 0x00, 0xe0, 0x00, 0xbf, 0x00, 0x28, 0x00, 0xd1, + 0x43, 0xe7, 0x21, 0x00, 0x38, 0x00, 0xff, 0xf7, 0xd3, 0xfb, 0x51, 0xe7, + 0x00, 0x29, 0x00, 0xd0, 0x4e, 0xe7, 0x8c, 0x22, 0x72, 0x43, 0x05, 0x32, + 0x01, 0x23, 0xaa, 0x18, 0x6a, 0xe7, 0x00, 0x29, 0x00, 0xd0, 0x45, 0xe7, + 0x8c, 0x22, 0x72, 0x43, 0x04, 0x32, 0xf5, 0xe7, 0x00, 0x29, 0xe8, 0xd0, + 0x02, 0x29, 0x00, 0xd0, 0x3c, 0xe7, 0x8c, 0x22, 0x72, 0x43, 0xa1, 0x78, + 0x06, 0x4b, 0xad, 0x18, 0x29, 0x71, 0x00, 0x2b, 0x00, 0xd1, 0x33, 0xe7, + 0x30, 0x00, 0x00, 0xe0, 0x00, 0xbf, 0x2f, 0xe7, 0xac, 0x11, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xb5, 0x1c, 0x4c, + 0x05, 0x00, 0xa0, 0x78, 0x62, 0x78, 0x88, 0x42, 0x0e, 0xd0, 0x91, 0x42, + 0x0c, 0xd0, 0x22, 0x00, 0x8e, 0x34, 0x20, 0x78, 0x8d, 0x32, 0x12, 0x78, + 0x88, 0x42, 0x02, 0xd0, 0x00, 0x26, 0x91, 0x42, 0x0f, 0xd1, 0x01, 0x20, + 0x13, 0x4c, 0x00, 0xe0, 0x00, 0x20, 0x62, 0x78, 0x8a, 0x42, 0x0a, 0xd1, + 0x11, 0x4a, 0x01, 0x26, 0x00, 0x2a, 0x04, 0xd0, 0x21, 0x00, 0xda, 0xb2, + 0x08, 0x31, 0x00, 0xe0, 0x00, 0xbf, 0x30, 0x00, 0x76, 0xbd, 0xa2, 0x78, + 0x01, 0x26, 0x8a, 0x42, 0xf9, 0xd1, 0x26, 0x00, 0x00, 0x22, 0x48, 0x36, + 0x9b, 0xb2, 0x11, 0x00, 0x00, 0x93, 0x33, 0x00, 0xfc, 0xf7, 0xf2, 0xfc, + 0x32, 0x00, 0x40, 0x23, 0x28, 0x00, 0xa1, 0x78, 0xff, 0xf7, 0x2c, 0xf8, + 0x06, 0x00, 0xe8, 0xe7, 0xac, 0x11, 0x00, 0x20, 0x38, 0x12, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x10, 0xb5, 0x00, 0x20, 0xfe, 0xf7, 0xa6, 0xfe, + 0x10, 0xbd, 0x10, 0xb5, 0xfe, 0xf7, 0x9c, 0xfe, 0x10, 0xbd, 0x00, 0x00, + 0x03, 0x00, 0x02, 0x79, 0x10, 0xb5, 0x44, 0x79, 0x07, 0x20, 0xdb, 0x78, + 0x04, 0x40, 0x24, 0x02, 0x9b, 0x07, 0x22, 0x43, 0x9b, 0x0f, 0x02, 0x2b, + 0x0d, 0xd0, 0x00, 0x20, 0x03, 0x2b, 0x12, 0xd0, 0x01, 0x2b, 0x07, 0xd1, + 0x02, 0x39, 0x4b, 0x42, 0x59, 0x41, 0x0b, 0x4b, 0xc9, 0x18, 0x91, 0x42, + 0x40, 0x41, 0xc0, 0xb2, 0x10, 0xbd, 0x00, 0x20, 0x02, 0x29, 0x06, 0xd1, + 0x07, 0x4b, 0xd0, 0x18, 0x43, 0x42, 0x58, 0x41, 0xf5, 0xe7, 0x02, 0x29, + 0x03, 0xd0, 0x40, 0x23, 0x93, 0x42, 0x40, 0x41, 0xef, 0xe7, 0x80, 0x23, + 0xdb, 0x00, 0xf9, 0xe7, 0xff, 0x03, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, + 0xf0, 0xb5, 0x00, 0x24, 0x7f, 0x26, 0x94, 0x42, 0x00, 0xd3, 0xf0, 0xbd, + 0x4d, 0x78, 0x05, 0x2d, 0x06, 0xd1, 0x8f, 0x78, 0x3d, 0x00, 0x35, 0x40, + 0x6d, 0x00, 0xff, 0x09, 0x45, 0x19, 0xeb, 0x55, 0x0d, 0x78, 0x64, 0x19, + 0xa4, 0xb2, 0x49, 0x19, 0xed, 0xe7, 0x8a, 0x18, 0x03, 0x00, 0x90, 0xb2, + 0x88, 0x42, 0x02, 0xd3, 0x9a, 0x89, 0x82, 0x42, 0x02, 0xd2, 0x5a, 0x89, + 0x80, 0x18, 0x80, 0xb2, 0x70, 0x47, 0x82, 0x88, 0x10, 0xb5, 0x8a, 0x42, + 0x04, 0xd8, 0x8b, 0x1a, 0x84, 0x89, 0x9b, 0xb2, 0x9c, 0x42, 0x03, 0xd2, + 0x43, 0x89, 0xd2, 0x18, 0x89, 0x1a, 0x8b, 0xb2, 0x03, 0x82, 0x10, 0xbd, + 0x10, 0xb5, 0x00, 0x28, 0x01, 0xd0, 0x07, 0xf0, 0xbb, 0xf8, 0x10, 0xbd, + 0xf7, 0xb5, 0x96, 0x08, 0x14, 0x00, 0x05, 0x00, 0x32, 0x00, 0x0b, 0x00, + 0x01, 0x3a, 0x11, 0x48, 0x92, 0xb2, 0x82, 0x42, 0x0e, 0xd1, 0x03, 0x23, + 0x22, 0x00, 0xb6, 0x00, 0x89, 0x19, 0x1a, 0x40, 0x1c, 0x42, 0x06, 0xd0, + 0x00, 0x23, 0x01, 0xa8, 0x01, 0x93, 0xfe, 0xf7, 0x0d, 0xfd, 0x01, 0x9b, + 0x2b, 0x60, 0xf7, 0xbd, 0x18, 0x78, 0x84, 0x46, 0x67, 0x46, 0x58, 0x78, + 0x00, 0x02, 0x38, 0x43, 0x9f, 0x78, 0x3f, 0x04, 0x07, 0x43, 0xd8, 0x78, + 0x04, 0x33, 0x00, 0x06, 0x38, 0x43, 0x28, 0x60, 0xdc, 0xe7, 0xc0, 0x46, + 0xff, 0xff, 0x00, 0x00, 0xf0, 0xb5, 0x0e, 0x00, 0x19, 0x00, 0x89, 0xb0, + 0x0e, 0xab, 0x05, 0x00, 0x18, 0x88, 0x0f, 0xab, 0x1b, 0x78, 0x0c, 0x1a, + 0x17, 0x00, 0x04, 0x93, 0xa4, 0xb2, 0x81, 0x42, 0x02, 0xd2, 0x6b, 0x89, + 0xe4, 0x1a, 0xa4, 0xb2, 0xab, 0x88, 0xa3, 0x42, 0x05, 0xd2, 0x28, 0x00, + 0xff, 0xf7, 0xa7, 0xff, 0x28, 0x8a, 0xac, 0x88, 0x80, 0xb2, 0x00, 0x2c, + 0x21, 0xd0, 0x23, 0x1c, 0xbc, 0x42, 0x00, 0xd9, 0x3b, 0x1c, 0x9c, 0xb2, + 0xab, 0x88, 0x83, 0x42, 0x1c, 0xd9, 0xea, 0x88, 0x1f, 0x1a, 0x11, 0x00, + 0xe3, 0x1a, 0xc3, 0x18, 0x53, 0x43, 0x50, 0x43, 0x9b, 0xb2, 0xbf, 0xb2, + 0x79, 0x43, 0x01, 0x93, 0x2b, 0x68, 0x89, 0xb2, 0x1b, 0x18, 0x03, 0x93, + 0x04, 0x9b, 0x02, 0x91, 0x01, 0x2b, 0x16, 0xd0, 0xbc, 0x42, 0x0a, 0xd8, + 0x30, 0x00, 0x62, 0x43, 0x03, 0x99, 0xfe, 0xf7, 0xb9, 0xfc, 0x20, 0x00, + 0x09, 0xb0, 0xf0, 0xbd, 0xc0, 0x1a, 0x80, 0xb2, 0xdd, 0xe7, 0x02, 0x9a, + 0x03, 0x99, 0x30, 0x00, 0xfe, 0xf7, 0xae, 0xfc, 0x02, 0x9b, 0x29, 0x68, + 0x01, 0x9a, 0xf0, 0x18, 0xed, 0xe7, 0xbc, 0x42, 0x06, 0xd8, 0x62, 0x43, + 0x03, 0x99, 0x92, 0xb2, 0x30, 0x00, 0xff, 0xf7, 0x7d, 0xff, 0xe6, 0xe7, + 0x03, 0x27, 0x02, 0x9b, 0x30, 0x00, 0xbb, 0x43, 0x1a, 0x00, 0x03, 0x99, + 0x05, 0x93, 0xff, 0xf7, 0x73, 0xff, 0x02, 0x9b, 0x3b, 0x40, 0x04, 0x93, + 0x02, 0x9b, 0x3b, 0x42, 0x2b, 0xd0, 0x04, 0x23, 0x04, 0x9a, 0x9b, 0x1a, + 0x01, 0x9a, 0x1f, 0x1c, 0x9b, 0xb2, 0x93, 0x42, 0x01, 0xd9, 0x6b, 0x46, + 0x9f, 0x88, 0x01, 0x9b, 0xbf, 0xb2, 0xdb, 0x1b, 0x9b, 0xb2, 0x05, 0x9a, + 0x01, 0x93, 0x00, 0x23, 0x94, 0x46, 0x07, 0x93, 0x03, 0x9b, 0x04, 0x9a, + 0x63, 0x44, 0x19, 0x00, 0x07, 0xa8, 0xfe, 0xf7, 0x77, 0xfc, 0x07, 0xaa, + 0x94, 0x46, 0x04, 0x9b, 0x2d, 0x68, 0x63, 0x44, 0x18, 0x00, 0x29, 0x00, + 0x3a, 0x00, 0xfe, 0xf7, 0x6d, 0xfc, 0x07, 0x9b, 0xe9, 0x19, 0x33, 0x60, + 0x01, 0x9b, 0x00, 0x2b, 0xad, 0xd0, 0x1a, 0x00, 0xc0, 0xe7, 0x29, 0x68, + 0xf8, 0xe7, 0x00, 0x00, 0xf7, 0xb5, 0x96, 0x08, 0x15, 0x00, 0x03, 0x00, + 0x32, 0x00, 0x01, 0x3a, 0x0d, 0x4c, 0x92, 0xb2, 0xa2, 0x42, 0x0c, 0xd1, + 0x03, 0x23, 0x2a, 0x00, 0xb6, 0x00, 0x80, 0x19, 0x1a, 0x40, 0x1d, 0x42, + 0x04, 0xd0, 0x0b, 0x68, 0x01, 0xa9, 0x01, 0x93, 0xfe, 0xf7, 0x4c, 0xfc, + 0xf7, 0xbd, 0x0c, 0x68, 0x27, 0x0a, 0x1c, 0x70, 0x5f, 0x70, 0x27, 0x0c, + 0x24, 0x0e, 0x9f, 0x70, 0xdc, 0x70, 0x04, 0x33, 0xe3, 0xe7, 0xc0, 0x46, + 0xff, 0xff, 0x00, 0x00, 0x70, 0xb5, 0x1c, 0x00, 0xd3, 0x1a, 0x0e, 0x00, + 0x05, 0x00, 0x11, 0x00, 0x9b, 0xb2, 0xa2, 0x42, 0x02, 0xd2, 0x42, 0x89, + 0x9b, 0x1a, 0x9b, 0xb2, 0xaa, 0x88, 0x9a, 0x42, 0x03, 0xd2, 0x28, 0x00, + 0xff, 0xf7, 0xf3, 0xfe, 0xab, 0x88, 0x18, 0x1e, 0x0a, 0xd0, 0xaa, 0x88, + 0xa2, 0x42, 0x08, 0xd9, 0xea, 0x88, 0x29, 0x68, 0x54, 0x43, 0x30, 0x00, + 0x09, 0x19, 0xfe, 0xf7, 0x1f, 0xfc, 0x01, 0x20, 0x70, 0xbd, 0xa4, 0x1a, + 0xa4, 0xb2, 0xf1, 0xe7, 0x10, 0xb5, 0x00, 0x28, 0x03, 0xd0, 0x01, 0x21, + 0x49, 0x42, 0x06, 0xf0, 0xe1, 0xff, 0x10, 0xbd, 0xf7, 0xb5, 0x04, 0x00, + 0x16, 0x00, 0x1f, 0x00, 0x0d, 0x00, 0x80, 0x69, 0xff, 0xf7, 0xf0, 0xff, + 0xe3, 0x89, 0x22, 0x8a, 0x9b, 0xb2, 0x29, 0x00, 0x01, 0x97, 0x00, 0x92, + 0x20, 0x00, 0x32, 0x00, 0xff, 0xf7, 0x08, 0xff, 0x21, 0x8a, 0x05, 0x00, + 0x02, 0x00, 0x89, 0xb2, 0x20, 0x00, 0xff, 0xf7, 0xb4, 0xfe, 0x20, 0x82, + 0xa0, 0x69, 0xff, 0xf7, 0xcb, 0xfe, 0x28, 0x00, 0xfe, 0xbd, 0xf0, 0xb5, + 0x04, 0x00, 0x89, 0xb0, 0x40, 0x69, 0x0d, 0x00, 0x17, 0x00, 0x04, 0x93, + 0xff, 0xf7, 0xd0, 0xff, 0xe3, 0x89, 0x22, 0x7a, 0x21, 0x8a, 0x9b, 0xb2, + 0x02, 0x93, 0x89, 0xb2, 0xa3, 0x88, 0x00, 0x2a, 0x37, 0xd1, 0x02, 0x9a, + 0x02, 0x98, 0x52, 0x1a, 0x92, 0xb2, 0x88, 0x42, 0x02, 0xd2, 0x61, 0x89, + 0x52, 0x1a, 0x92, 0xb2, 0x9a, 0x1a, 0x11, 0x1c, 0x92, 0xb2, 0xba, 0x42, + 0x00, 0xd9, 0x39, 0x1c, 0x8f, 0xb2, 0x02, 0x9e, 0xb3, 0x42, 0x2d, 0xd9, + 0xe2, 0x88, 0x99, 0x1b, 0x10, 0x00, 0xfb, 0x1a, 0xf3, 0x18, 0x53, 0x43, + 0x56, 0x43, 0x89, 0xb2, 0x9b, 0xb2, 0x48, 0x43, 0x01, 0x93, 0x23, 0x68, + 0x80, 0xb2, 0x9e, 0x19, 0x04, 0x9b, 0x03, 0x90, 0x01, 0x2b, 0x28, 0xd0, + 0x8f, 0x42, 0x1c, 0xd8, 0x29, 0x00, 0x30, 0x00, 0x7a, 0x43, 0xfe, 0xf7, + 0xb5, 0xfb, 0x3a, 0x00, 0x02, 0x99, 0x20, 0x00, 0xff, 0xf7, 0x6b, 0xfe, + 0xe0, 0x81, 0x60, 0x69, 0xff, 0xf7, 0x82, 0xfe, 0x38, 0x00, 0x09, 0xb0, + 0xf0, 0xbd, 0xe2, 0x88, 0x9f, 0x42, 0xd4, 0xd3, 0xff, 0x1a, 0x7a, 0x43, + 0x02, 0x91, 0x1f, 0x00, 0xad, 0x18, 0xce, 0xe7, 0xf6, 0x1a, 0xb6, 0xb2, + 0xcc, 0xe7, 0x29, 0x00, 0x03, 0x9a, 0x30, 0x00, 0xfe, 0xf7, 0x98, 0xfb, + 0x03, 0x9b, 0x01, 0x9a, 0x20, 0x68, 0xe9, 0x18, 0xdb, 0xe7, 0x8f, 0x42, + 0x06, 0xd8, 0x29, 0x00, 0x30, 0x00, 0x7a, 0x43, 0x92, 0xb2, 0xff, 0xf7, + 0x29, 0xff, 0xd4, 0xe7, 0x03, 0x23, 0x03, 0x9a, 0x29, 0x00, 0x9a, 0x43, + 0x30, 0x00, 0x05, 0x92, 0xff, 0xf7, 0x20, 0xff, 0x03, 0x23, 0x03, 0x9a, + 0x1a, 0x40, 0x04, 0x92, 0x03, 0x9a, 0x1a, 0x42, 0x2a, 0xd0, 0x04, 0x9a, + 0x01, 0x33, 0x9b, 0x1a, 0x01, 0x99, 0x1a, 0x1c, 0x9b, 0xb2, 0x8b, 0x42, + 0x01, 0xd9, 0x6b, 0x46, 0x9a, 0x88, 0x93, 0xb2, 0x03, 0x93, 0x03, 0x9a, + 0x01, 0x9b, 0x07, 0xa9, 0x9b, 0x1a, 0x9b, 0xb2, 0x01, 0x93, 0x2b, 0x68, + 0x04, 0x9a, 0x07, 0x93, 0x05, 0x9b, 0xf0, 0x18, 0xfe, 0xf7, 0x62, 0xfb, + 0x07, 0xaa, 0x94, 0x46, 0x04, 0x9b, 0x26, 0x68, 0x63, 0x44, 0x19, 0x00, + 0x30, 0x00, 0x03, 0x9a, 0xfe, 0xf7, 0x58, 0xfb, 0x03, 0x9b, 0xf0, 0x18, + 0x01, 0x9b, 0x00, 0x2b, 0x9d, 0xd0, 0x1a, 0x00, 0x29, 0x00, 0xc2, 0xe7, + 0x20, 0x68, 0xf7, 0xe7, 0xf7, 0xb5, 0x01, 0x93, 0x08, 0xab, 0x1f, 0x78, + 0x80, 0x23, 0x04, 0x00, 0x15, 0x00, 0x00, 0x26, 0x00, 0x91, 0x1b, 0x02, + 0x9a, 0x42, 0x1a, 0xd8, 0x40, 0x69, 0xff, 0xf7, 0x25, 0xff, 0xa0, 0x69, + 0xff, 0xf7, 0x22, 0xff, 0x00, 0x9b, 0xa5, 0x80, 0x23, 0x60, 0x6d, 0x00, + 0x01, 0x9b, 0xad, 0xb2, 0xe3, 0x80, 0x6b, 0x1e, 0x6d, 0x42, 0xe6, 0x81, + 0x60, 0x69, 0xa3, 0x81, 0x26, 0x82, 0x27, 0x72, 0x65, 0x81, 0xff, 0xf7, + 0x01, 0xfe, 0xa0, 0x69, 0xff, 0xf7, 0xfe, 0xfd, 0x01, 0x36, 0x30, 0x00, + 0xfe, 0xbd, 0xc1, 0x89, 0x02, 0x8a, 0x8b, 0x1a, 0x9b, 0xb2, 0x91, 0x42, + 0x02, 0xd2, 0x42, 0x89, 0x9b, 0x1a, 0x9b, 0xb2, 0x82, 0x88, 0x10, 0x1c, + 0x9a, 0x42, 0x00, 0xd9, 0x18, 0x1c, 0x80, 0xb2, 0x70, 0x47, 0x03, 0x00, + 0xc0, 0x89, 0x1b, 0x8a, 0xc0, 0x1a, 0x43, 0x42, 0x58, 0x41, 0xc0, 0xb2, + 0x70, 0x47, 0x10, 0xb5, 0xc4, 0x89, 0x01, 0x8a, 0x82, 0x88, 0x63, 0x1a, + 0x9b, 0xb2, 0x8c, 0x42, 0x02, 0xd2, 0x40, 0x89, 0x1b, 0x1a, 0x9b, 0xb2, + 0xd0, 0x1a, 0x80, 0xb2, 0x10, 0xbd, 0x70, 0xb5, 0x04, 0x00, 0x0d, 0x00, + 0x80, 0x69, 0xff, 0xf7, 0xdf, 0xfe, 0xe2, 0x89, 0x23, 0x8a, 0x29, 0x00, + 0x9b, 0xb2, 0x20, 0x00, 0x92, 0xb2, 0xff, 0xf7, 0xb3, 0xfe, 0x21, 0x8a, + 0x05, 0x00, 0x82, 0xb2, 0x89, 0xb2, 0x20, 0x00, 0xff, 0xf7, 0xa5, 0xfd, + 0x20, 0x82, 0xa0, 0x69, 0xff, 0xf7, 0xbc, 0xfd, 0x28, 0x00, 0x70, 0xbd, + 0x10, 0xb5, 0x00, 0x23, 0xff, 0xf7, 0xce, 0xfe, 0x10, 0xbd, 0x70, 0xb5, + 0x04, 0x00, 0x0d, 0x00, 0x80, 0x69, 0xff, 0xf7, 0xbf, 0xfe, 0xe2, 0x89, + 0x23, 0x8a, 0x29, 0x00, 0x92, 0xb2, 0x9b, 0xb2, 0x20, 0x00, 0xff, 0xf7, + 0x93, 0xfe, 0x05, 0x00, 0xa0, 0x69, 0xff, 0xf7, 0xa3, 0xfd, 0x28, 0x00, + 0x70, 0xbd, 0x70, 0xb5, 0x04, 0x00, 0x40, 0x69, 0x0e, 0x00, 0xff, 0xf7, + 0xab, 0xfe, 0xe2, 0x89, 0x21, 0x8a, 0x95, 0xb2, 0x53, 0x1a, 0x9b, 0xb2, + 0x91, 0x42, 0x02, 0xd9, 0x62, 0x89, 0x9b, 0x1a, 0x9b, 0xb2, 0xa2, 0x88, + 0x9a, 0x42, 0x1a, 0xd1, 0x20, 0x7a, 0x2b, 0x00, 0x00, 0x28, 0x02, 0xd1, + 0x70, 0xbd, 0x9b, 0x1a, 0x9b, 0xb2, 0x93, 0x42, 0xfb, 0xd2, 0xe2, 0x88, + 0x21, 0x68, 0x53, 0x43, 0xc8, 0x18, 0x31, 0x00, 0xfe, 0xf7, 0xa8, 0xfa, + 0x01, 0x22, 0x29, 0x00, 0x20, 0x00, 0xff, 0xf7, 0x5e, 0xfd, 0xe0, 0x81, + 0x60, 0x69, 0xff, 0xf7, 0x75, 0xfd, 0x01, 0x20, 0xe8, 0xe7, 0x2b, 0x00, + 0xe9, 0xe7, 0x10, 0xb5, 0x00, 0x2a, 0x03, 0xd0, 0x00, 0x23, 0xff, 0xf7, + 0xa2, 0xfe, 0x02, 0x00, 0x10, 0x00, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x00, + 0x40, 0x69, 0xff, 0xf7, 0x73, 0xfe, 0xa0, 0x69, 0xff, 0xf7, 0x70, 0xfe, + 0x00, 0x23, 0xe3, 0x81, 0x23, 0x82, 0xa3, 0x88, 0x60, 0x69, 0x5b, 0x00, + 0x9b, 0xb2, 0x5a, 0x1e, 0x5b, 0x42, 0xa2, 0x81, 0x63, 0x81, 0xff, 0xf7, + 0x53, 0xfd, 0xa0, 0x69, 0xff, 0xf7, 0x50, 0xfd, 0x01, 0x20, 0x10, 0xbd, + 0x70, 0xb5, 0x04, 0x00, 0x0d, 0x00, 0x40, 0x69, 0xff, 0xf7, 0x58, 0xfe, + 0xa0, 0x69, 0xff, 0xf7, 0x55, 0xfe, 0x60, 0x69, 0x25, 0x72, 0xff, 0xf7, + 0x41, 0xfd, 0xa0, 0x69, 0xff, 0xf7, 0x3e, 0xfd, 0x01, 0x20, 0x70, 0xbd, + 0xef, 0xf3, 0x10, 0x80, 0x72, 0xb6, 0x03, 0x4a, 0x13, 0x68, 0x00, 0x2b, + 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x70, 0x47, 0x2c, 0x01, 0x00, 0xd0, + 0xbf, 0xf3, 0x5f, 0x8f, 0x00, 0x22, 0x02, 0x4b, 0x1a, 0x60, 0x80, 0xf3, + 0x10, 0x88, 0x70, 0x47, 0x2c, 0x01, 0x00, 0xd0, 0x07, 0x22, 0xcb, 0x08, + 0xc3, 0x5c, 0x01, 0x20, 0x11, 0x40, 0x88, 0x40, 0x18, 0x40, 0x43, 0x1e, + 0x98, 0x41, 0xc0, 0xb2, 0x70, 0x47, 0xf8, 0xb5, 0x05, 0x00, 0x0c, 0x00, + 0x17, 0x00, 0xff, 0xf7, 0xd9, 0xff, 0x21, 0x00, 0x06, 0x00, 0x28, 0x00, + 0xff, 0xf7, 0xea, 0xff, 0x00, 0x28, 0x03, 0xd0, 0x21, 0x00, 0x38, 0x00, + 0xfd, 0xf7, 0xf2, 0xfa, 0x07, 0x21, 0x01, 0x23, 0xe2, 0x08, 0x0c, 0x40, + 0xa3, 0x40, 0xa9, 0x5c, 0x30, 0x00, 0x0b, 0x43, 0xab, 0x54, 0xff, 0xf7, + 0xcf, 0xff, 0xf8, 0xbd, 0xf7, 0xb5, 0x05, 0x00, 0x14, 0x00, 0x1f, 0x00, + 0x01, 0x91, 0xff, 0xf7, 0xbb, 0xff, 0x06, 0x00, 0xbc, 0x42, 0x02, 0xd9, + 0x01, 0x24, 0x64, 0x42, 0x0d, 0xe0, 0x21, 0x00, 0x28, 0x00, 0xff, 0xf7, + 0xc7, 0xff, 0x00, 0x28, 0x12, 0xd1, 0x07, 0x22, 0x01, 0x23, 0x22, 0x40, + 0x93, 0x40, 0xe1, 0x08, 0x6a, 0x5c, 0x13, 0x43, 0x6b, 0x54, 0x30, 0x00, + 0xff, 0xf7, 0xb0, 0xff, 0x00, 0x2c, 0x07, 0xda, 0x01, 0x9b, 0x00, 0x2b, + 0x04, 0xd0, 0x08, 0x98, 0xfd, 0xf7, 0xc0, 0xfa, 0x01, 0x34, 0xdf, 0xe7, + 0x20, 0x00, 0xfe, 0xbd, 0x02, 0x4b, 0x18, 0x68, 0x80, 0x07, 0xc0, 0x0f, + 0x70, 0x47, 0xc0, 0x46, 0x00, 0xc0, 0x06, 0x40, 0xf0, 0xb5, 0x85, 0xb0, + 0x03, 0x92, 0x0a, 0x9a, 0x05, 0x00, 0x0f, 0x00, 0x00, 0x20, 0x9a, 0x42, + 0x40, 0xd8, 0x0c, 0x24, 0x1a, 0x0e, 0x1b, 0x02, 0x02, 0x92, 0x01, 0x93, + 0x0a, 0x9a, 0x03, 0x00, 0x02, 0x99, 0x01, 0x98, 0xfd, 0xf7, 0x26, 0xfb, + 0x6c, 0x43, 0x28, 0x4b, 0x06, 0x00, 0xe4, 0x18, 0x63, 0x68, 0x83, 0x42, + 0x00, 0xd2, 0x60, 0x60, 0x2b, 0x1f, 0xdb, 0xb2, 0x00, 0x93, 0xc0, 0x23, + 0x00, 0x9a, 0x9b, 0x01, 0x23, 0x43, 0x01, 0x2a, 0x26, 0xd8, 0x01, 0x2f, + 0x24, 0xd1, 0x03, 0x22, 0x1a, 0x60, 0xa3, 0x68, 0x3b, 0x42, 0xfc, 0xd0, + 0x03, 0x9a, 0x23, 0x68, 0x52, 0x01, 0x5a, 0x40, 0x80, 0x21, 0xe0, 0x23, + 0x49, 0x01, 0x1a, 0x40, 0x00, 0x9b, 0x21, 0x43, 0x0a, 0x60, 0x01, 0x2b, + 0x21, 0xd9, 0x80, 0x23, 0x80, 0x22, 0x9b, 0x01, 0x23, 0x43, 0x12, 0x01, + 0x1a, 0x60, 0x01, 0x98, 0x00, 0x23, 0x32, 0x00, 0x02, 0x99, 0x66, 0x60, + 0xfd, 0xf7, 0xf4, 0xfa, 0x10, 0x4b, 0xad, 0x00, 0x58, 0x51, 0x01, 0x20, + 0x05, 0xb0, 0xf0, 0xbd, 0x80, 0x22, 0x12, 0x01, 0x1a, 0x60, 0x0c, 0x4b, + 0xaa, 0x00, 0xd1, 0x58, 0x00, 0x29, 0xd7, 0xd0, 0x58, 0x69, 0xfd, 0xf7, + 0xa1, 0xfa, 0x01, 0x30, 0x01, 0x38, 0xfd, 0xd1, 0xd0, 0xe7, 0x03, 0x22, + 0x23, 0x68, 0x7b, 0x40, 0x13, 0x40, 0x0b, 0x60, 0x01, 0x23, 0xbb, 0x40, + 0xa2, 0x68, 0x13, 0x42, 0xfc, 0xd0, 0xd2, 0xe7, 0x00, 0x80, 0x00, 0x40, + 0x3c, 0x14, 0x00, 0x20, 0x73, 0xb5, 0x0c, 0x20, 0x00, 0xf0, 0xe6, 0xf8, + 0xff, 0xf7, 0x88, 0xff, 0x00, 0x28, 0x0a, 0xd0, 0x00, 0x23, 0x2c, 0x4a, + 0x2c, 0x48, 0x99, 0x00, 0x01, 0x33, 0x88, 0x50, 0x0a, 0x2b, 0xfa, 0xd1, + 0x2a, 0x4b, 0x53, 0x62, 0x73, 0xbd, 0x2a, 0x4d, 0xa8, 0x67, 0x00, 0xf0, + 0xdb, 0xf8, 0x01, 0x22, 0x28, 0x4b, 0x1a, 0x60, 0x6b, 0x6c, 0x01, 0x2b, + 0xfc, 0xd1, 0x03, 0x22, 0x26, 0x4b, 0x1a, 0x60, 0xac, 0x6b, 0x01, 0x2c, + 0xfc, 0xd1, 0x02, 0x25, 0x05, 0x26, 0x21, 0x00, 0x00, 0x95, 0x06, 0x23, + 0x22, 0x4a, 0x23, 0x48, 0x00, 0xf0, 0x70, 0xf8, 0x33, 0x00, 0x21, 0x00, + 0x21, 0x4a, 0x22, 0x48, 0x00, 0x96, 0x00, 0xf0, 0x69, 0xf8, 0x21, 0x4b, + 0x29, 0x00, 0x21, 0x4d, 0x00, 0x93, 0x00, 0x22, 0x04, 0x20, 0xff, 0xf7, + 0x5b, 0xff, 0x2b, 0x00, 0x21, 0x00, 0x00, 0x22, 0x30, 0x00, 0x00, 0x95, + 0xff, 0xf7, 0x54, 0xff, 0x00, 0x22, 0x10, 0x4c, 0x11, 0x00, 0x23, 0x00, + 0x00, 0x94, 0x07, 0x20, 0xff, 0xf7, 0x4c, 0xff, 0x00, 0x22, 0x23, 0x00, + 0x11, 0x00, 0x00, 0x94, 0x08, 0x20, 0xff, 0xf7, 0x45, 0xff, 0x00, 0x22, + 0x09, 0x4b, 0x11, 0x00, 0x00, 0x93, 0x09, 0x20, 0x23, 0x00, 0xff, 0xf7, + 0x3d, 0xff, 0x00, 0x22, 0x2b, 0x00, 0x11, 0x00, 0x00, 0x95, 0x06, 0x20, + 0xff, 0xf7, 0x36, 0xff, 0xb0, 0xe7, 0xc0, 0x46, 0x3c, 0x14, 0x00, 0x20, + 0x00, 0x6c, 0xdc, 0x02, 0x1b, 0xb7, 0x00, 0x00, 0x00, 0x80, 0x00, 0x40, + 0x3c, 0xb0, 0x00, 0x40, 0x30, 0xb0, 0x00, 0x40, 0x00, 0x2f, 0x68, 0x59, + 0x00, 0x80, 0x02, 0x40, 0x00, 0x8c, 0x86, 0x47, 0x00, 0xc0, 0x02, 0x40, + 0x00, 0x1b, 0xb7, 0x00, 0x40, 0x59, 0x73, 0x07, 0x01, 0x4b, 0x80, 0x00, + 0xc0, 0x58, 0x70, 0x47, 0x3c, 0x14, 0x00, 0x20, 0x02, 0x4b, 0xc9, 0x18, + 0x89, 0x00, 0x01, 0x60, 0x70, 0x47, 0xc0, 0x46, 0x40, 0x00, 0x00, 0x34, + 0x03, 0x4b, 0xc9, 0x18, 0x89, 0x00, 0x01, 0x60, 0xbf, 0xf3, 0x5f, 0x8f, + 0x70, 0x47, 0xc0, 0x46, 0x40, 0x00, 0x00, 0x34, 0x10, 0xb5, 0x04, 0x00, + 0x01, 0x20, 0xfc, 0xf7, 0x61, 0xf8, 0x01, 0x00, 0x20, 0x00, 0xff, 0xf7, + 0xed, 0xff, 0x10, 0xbd, 0xf8, 0xb5, 0x04, 0x00, 0x0c, 0x20, 0x17, 0x00, + 0x1e, 0x00, 0x0d, 0x00, 0xfd, 0xf7, 0xea, 0xf9, 0x1d, 0x49, 0x41, 0x43, + 0x38, 0x00, 0xfd, 0xf7, 0xe5, 0xf9, 0x06, 0x9a, 0x33, 0x04, 0x12, 0x03, + 0x13, 0x43, 0x22, 0x68, 0x00, 0x2a, 0x0f, 0xda, 0x3f, 0x21, 0x22, 0x68, + 0x0a, 0x40, 0xaa, 0x42, 0x0a, 0xd1, 0xa2, 0x68, 0x12, 0x05, 0x12, 0x0d, + 0x82, 0x42, 0x05, 0xd1, 0xee, 0x21, 0xe2, 0x68, 0xc9, 0x02, 0x0a, 0x40, + 0x9a, 0x42, 0x1b, 0xd0, 0x10, 0x4a, 0x94, 0x42, 0x19, 0xd0, 0x80, 0x22, + 0x52, 0x01, 0x0f, 0x49, 0x0f, 0x4e, 0x0a, 0x60, 0x0f, 0x49, 0x0a, 0x60, + 0x17, 0x00, 0xb1, 0x68, 0x8f, 0x43, 0xfb, 0xd1, 0xc0, 0x22, 0x21, 0x1d, + 0x92, 0x01, 0x0a, 0x43, 0x21, 0x21, 0x25, 0x60, 0xa0, 0x60, 0x11, 0x60, + 0x21, 0x68, 0x00, 0x29, 0xfc, 0xda, 0xe3, 0x60, 0x08, 0x23, 0x13, 0x60, + 0xf8, 0xbd, 0x80, 0x22, 0x92, 0x01, 0xe4, 0xe7, 0x40, 0x42, 0x0f, 0x00, + 0x00, 0xc0, 0x02, 0x40, 0x00, 0xe0, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x40, + 0x00, 0xf0, 0x00, 0x40, 0x80, 0x23, 0x02, 0x4a, 0x9b, 0x00, 0x03, 0x43, + 0xd3, 0x62, 0x70, 0x47, 0x00, 0x80, 0x05, 0x40, 0xaa, 0x22, 0x06, 0x4b, + 0x12, 0x01, 0x1a, 0x60, 0x21, 0x32, 0xff, 0x32, 0xda, 0x60, 0x04, 0x49, + 0x04, 0x4a, 0x11, 0x60, 0x5a, 0x68, 0x00, 0x2a, 0xfc, 0xda, 0x70, 0x47, + 0x00, 0x40, 0x02, 0x40, 0x00, 0xb0, 0xfa, 0x00, 0x00, 0x60, 0x02, 0x40, + 0x70, 0xb5, 0x00, 0x24, 0x09, 0x26, 0x88, 0xb0, 0x05, 0x00, 0x32, 0x00, + 0x21, 0x00, 0x01, 0xa8, 0x00, 0x94, 0xfe, 0xf7, 0x75, 0xf8, 0x32, 0x00, + 0x21, 0x00, 0x05, 0xa8, 0x04, 0x94, 0xfe, 0xf7, 0x6f, 0xf8, 0x4b, 0x23, + 0x6a, 0x46, 0x68, 0x46, 0x13, 0x70, 0x04, 0xa9, 0x0d, 0x22, 0x06, 0xf0, + 0xfb, 0xfb, 0x15, 0x21, 0x08, 0x22, 0x28, 0x00, 0x69, 0x44, 0xfe, 0xf7, + 0x67, 0xf8, 0x08, 0xb0, 0x70, 0xbd, 0x00, 0x00, 0x7f, 0x23, 0x03, 0x40, + 0xf0, 0xb5, 0xc4, 0x09, 0x5d, 0x00, 0x27, 0x4e, 0x2f, 0x19, 0x7f, 0x01, + 0xf7, 0x19, 0xb8, 0x70, 0x01, 0x20, 0xa0, 0x43, 0x78, 0x70, 0x00, 0x20, + 0xf8, 0x70, 0x98, 0x01, 0xb9, 0x83, 0xba, 0x77, 0x8c, 0x46, 0xdf, 0x00, + 0x30, 0x18, 0x01, 0x2c, 0x10, 0xd1, 0x1f, 0x49, 0x7f, 0x18, 0x87, 0x62, + 0x00, 0x27, 0x28, 0x19, 0x40, 0x01, 0x30, 0x18, 0x80, 0x68, 0x07, 0x60, + 0xbb, 0x42, 0x09, 0xd1, 0x64, 0x01, 0x36, 0x19, 0x73, 0x60, 0x19, 0x4b, + 0xf3, 0x60, 0xf0, 0xbd, 0x18, 0x49, 0x7f, 0x18, 0x87, 0x60, 0xed, 0xe7, + 0x58, 0x1e, 0x9b, 0x01, 0xc0, 0x00, 0xf3, 0x18, 0x01, 0x2c, 0x1c, 0xd1, + 0x14, 0x49, 0x40, 0x18, 0x58, 0x62, 0x61, 0x46, 0x3f, 0x23, 0x3f, 0x31, + 0x89, 0xb2, 0x99, 0x43, 0x02, 0x2a, 0x00, 0xd1, 0x49, 0x00, 0x10, 0x48, + 0x2d, 0x19, 0x03, 0x68, 0x6d, 0x01, 0x59, 0x18, 0x01, 0x60, 0x0e, 0x49, + 0x76, 0x19, 0xf3, 0x60, 0x92, 0x06, 0x4b, 0x40, 0x1a, 0x43, 0x80, 0x23, + 0x1b, 0x06, 0x1a, 0x43, 0x73, 0x68, 0x1a, 0x60, 0xd7, 0xe7, 0x09, 0x49, + 0x40, 0x18, 0x58, 0x60, 0xe1, 0xe7, 0xc0, 0x46, 0x68, 0x14, 0x00, 0x20, + 0x80, 0x00, 0x10, 0x50, 0x00, 0x01, 0x10, 0x50, 0x84, 0x00, 0x10, 0x50, + 0x08, 0x00, 0x10, 0x50, 0x68, 0x18, 0x00, 0x20, 0x00, 0x00, 0x10, 0x50, + 0x0c, 0x00, 0x10, 0x50, 0x00, 0x23, 0x19, 0x00, 0x10, 0xb5, 0x09, 0x48, + 0xda, 0x00, 0x12, 0x18, 0x01, 0x33, 0x91, 0x60, 0xd1, 0x60, 0x0f, 0x2b, + 0xf7, 0xd1, 0xf0, 0x22, 0x92, 0x00, 0x00, 0x21, 0x04, 0x48, 0xfd, 0xf7, + 0xe9, 0xff, 0x04, 0x4b, 0x04, 0x4a, 0x1a, 0x60, 0x10, 0xbd, 0xc0, 0x46, + 0x00, 0x00, 0x10, 0x50, 0xa8, 0x14, 0x00, 0x20, 0x68, 0x18, 0x00, 0x20, + 0x80, 0x01, 0x10, 0x50, 0x43, 0x4b, 0xf0, 0xb5, 0x1e, 0x68, 0x80, 0x24, + 0x35, 0x00, 0x64, 0x02, 0x85, 0xb0, 0x25, 0x40, 0x26, 0x42, 0x0d, 0xd0, + 0x01, 0x22, 0x3f, 0x4b, 0x00, 0x20, 0xda, 0x70, 0x04, 0x33, 0xda, 0x77, + 0x3d, 0x49, 0xfe, 0xf7, 0x95, 0xf9, 0x80, 0x22, 0x25, 0x00, 0x3c, 0x4b, + 0x92, 0x02, 0x1a, 0x65, 0x10, 0x23, 0x1e, 0x42, 0x0c, 0xd0, 0x1d, 0x43, + 0x39, 0x4b, 0x01, 0x27, 0x9b, 0x6d, 0x03, 0x93, 0x00, 0x23, 0x02, 0x93, + 0x03, 0x9b, 0x00, 0x2b, 0x02, 0xd0, 0x02, 0x9b, 0x20, 0x2b, 0x34, 0xd1, + 0x80, 0x23, 0x5b, 0x01, 0x1e, 0x42, 0x0e, 0xd0, 0x00, 0x24, 0x1d, 0x43, + 0x30, 0x4b, 0x1c, 0x60, 0xff, 0xf7, 0xb0, 0xff, 0x01, 0x22, 0x21, 0x00, + 0x20, 0x00, 0xfe, 0xf7, 0x5c, 0xf9, 0x80, 0x22, 0x2a, 0x4b, 0x12, 0x03, + 0x1a, 0x65, 0x80, 0x23, 0xdb, 0x01, 0x1e, 0x42, 0x08, 0xd0, 0x01, 0x22, + 0x04, 0x21, 0x00, 0x20, 0x1d, 0x43, 0xfe, 0xf7, 0x3d, 0xf9, 0x10, 0x22, + 0x23, 0x4b, 0x1a, 0x65, 0x80, 0x23, 0x1b, 0x02, 0x1e, 0x42, 0x09, 0xd0, + 0x01, 0x22, 0x05, 0x21, 0x00, 0x20, 0x1d, 0x43, 0xfe, 0xf7, 0x30, 0xf9, + 0x80, 0x22, 0x1d, 0x4b, 0x12, 0x01, 0x1a, 0x65, 0xb5, 0x42, 0x2c, 0xd0, + 0x29, 0x00, 0x1c, 0x48, 0x71, 0x40, 0xfd, 0xf7, 0x43, 0xf8, 0x03, 0x9b, + 0x1f, 0x42, 0x1e, 0xd0, 0x16, 0x4b, 0x02, 0x9a, 0x9f, 0x65, 0x02, 0x9b, + 0x5c, 0x08, 0x01, 0x23, 0x64, 0x00, 0x93, 0x43, 0xe4, 0x18, 0x10, 0x4b, + 0x64, 0x01, 0xe4, 0x18, 0x20, 0x00, 0x00, 0xf0, 0xc1, 0xf9, 0x00, 0x28, + 0x0a, 0xd0, 0x01, 0x23, 0xa2, 0x8a, 0xa1, 0x78, 0x00, 0x93, 0x00, 0x23, + 0x18, 0x00, 0xfe, 0xf7, 0x42, 0xf9, 0x20, 0x00, 0x00, 0xf0, 0x42, 0xf9, + 0x03, 0x9b, 0xbb, 0x43, 0x03, 0x93, 0x02, 0x9b, 0x7f, 0x00, 0x01, 0x33, + 0xdb, 0xb2, 0x02, 0x93, 0x9c, 0xe7, 0x05, 0xb0, 0xf0, 0xbd, 0xc0, 0x46, + 0x98, 0x00, 0x11, 0x50, 0x68, 0x14, 0x00, 0x20, 0x00, 0x00, 0x10, 0x50, + 0x00, 0x30, 0x11, 0x50, 0x00, 0x00, 0x11, 0x50, 0xd4, 0x00, 0x01, 0x10, + 0x10, 0xb5, 0x01, 0x21, 0x05, 0x20, 0xfb, 0xf7, 0xf3, 0xfe, 0x10, 0xbd, + 0x00, 0x22, 0x10, 0xb5, 0x11, 0x00, 0x02, 0x48, 0x00, 0xf0, 0x86, 0xf9, + 0x10, 0xbd, 0xc0, 0x46, 0x88, 0x14, 0x00, 0x20, 0x80, 0x22, 0x02, 0x4b, + 0x52, 0x02, 0xda, 0x64, 0x70, 0x47, 0xc0, 0x46, 0x00, 0x20, 0x11, 0x50, + 0x70, 0xb5, 0x05, 0x00, 0x00, 0xf0, 0xe8, 0xf8, 0x0c, 0x23, 0x40, 0x26, + 0x11, 0x4c, 0x05, 0x20, 0xa3, 0x67, 0x11, 0x49, 0xfb, 0xf7, 0xec, 0xfe, + 0x32, 0x00, 0x00, 0x21, 0x0f, 0x48, 0xfd, 0xf7, 0x1f, 0xff, 0x00, 0x22, + 0x31, 0x00, 0x10, 0x00, 0xff, 0xf7, 0xbc, 0xfe, 0x31, 0x00, 0x00, 0x22, + 0x80, 0x20, 0xff, 0xf7, 0xb7, 0xfe, 0xff, 0xf7, 0x19, 0xff, 0x01, 0x23, + 0x23, 0x64, 0x80, 0x23, 0x9b, 0x05, 0xe3, 0x64, 0x06, 0x4b, 0x90, 0x34, + 0x28, 0x00, 0x23, 0x60, 0xff, 0xf7, 0xd0, 0xff, 0x70, 0xbd, 0xc0, 0x46, + 0x00, 0x00, 0x11, 0x50, 0x39, 0x95, 0x00, 0x10, 0x68, 0x14, 0x00, 0x20, + 0x10, 0xd0, 0x01, 0x00, 0x0b, 0x78, 0x5b, 0x06, 0x05, 0xd1, 0x4b, 0x78, + 0x05, 0x2b, 0x02, 0xd1, 0x8a, 0x78, 0x01, 0x4b, 0x1a, 0x60, 0x70, 0x47, + 0x00, 0x00, 0x11, 0x50, 0x07, 0x23, 0x08, 0x00, 0x10, 0xb5, 0xca, 0x78, + 0x0c, 0x79, 0x49, 0x79, 0x92, 0x07, 0x19, 0x40, 0x09, 0x02, 0x80, 0x78, + 0x92, 0x0f, 0x21, 0x43, 0xff, 0xf7, 0x86, 0xfe, 0x01, 0x20, 0x10, 0xbd, + 0x10, 0xb5, 0xff, 0xf7, 0xe5, 0xfe, 0x10, 0xbd, 0x10, 0xb5, 0x7f, 0x20, + 0x0c, 0x00, 0x20, 0x40, 0x40, 0x00, 0xe4, 0x09, 0x11, 0x00, 0x00, 0x19, + 0x1a, 0x00, 0x03, 0x4b, 0x40, 0x01, 0xc0, 0x18, 0x00, 0xf0, 0x1a, 0xf9, + 0x01, 0x20, 0x10, 0xbd, 0x68, 0x14, 0x00, 0x20, 0x7f, 0x22, 0x08, 0x00, + 0x10, 0xb5, 0x10, 0x40, 0xcc, 0x09, 0x11, 0x42, 0x03, 0xd1, 0x07, 0x49, + 0x7d, 0x3a, 0x12, 0x1b, 0x8a, 0x66, 0x80, 0x22, 0x40, 0x00, 0x05, 0x4b, + 0x00, 0x19, 0x40, 0x01, 0x00, 0x21, 0xc0, 0x18, 0x12, 0x01, 0x00, 0xf0, + 0x9f, 0xf8, 0x10, 0xbd, 0x00, 0x20, 0x11, 0x50, 0x68, 0x14, 0x00, 0x20, + 0x7f, 0x22, 0x08, 0x00, 0x10, 0xb5, 0x10, 0x40, 0x11, 0x42, 0x0a, 0xd0, + 0x00, 0x22, 0xc9, 0x09, 0x40, 0x00, 0x40, 0x18, 0x03, 0x49, 0x40, 0x01, + 0x08, 0x18, 0xc2, 0x70, 0x02, 0x49, 0x00, 0xf0, 0x89, 0xf8, 0x10, 0xbd, + 0x68, 0x14, 0x00, 0x20, 0xff, 0xf7, 0xff, 0xff, 0xf8, 0xb5, 0x82, 0x8b, + 0x43, 0x8a, 0x04, 0x00, 0x0f, 0x00, 0x16, 0x1c, 0x9a, 0x42, 0x00, 0xd9, + 0x1e, 0x1c, 0xe1, 0x78, 0xb6, 0xb2, 0x0d, 0x00, 0x9b, 0x1b, 0x63, 0x82, + 0x6b, 0x1e, 0x9d, 0x41, 0x01, 0x23, 0x80, 0x22, 0x4b, 0x40, 0xd2, 0x00, + 0xe3, 0x70, 0x63, 0x78, 0x32, 0x43, 0x6d, 0x03, 0x15, 0x43, 0x00, 0x2b, + 0x0c, 0xd1, 0xe3, 0x68, 0xb8, 0x01, 0x32, 0x00, 0x18, 0x18, 0xa1, 0x69, + 0xfd, 0xf7, 0x80, 0xfe, 0xa3, 0x69, 0x9e, 0x19, 0x80, 0x23, 0x1b, 0x02, + 0xa6, 0x61, 0x1d, 0x43, 0x63, 0x8a, 0x00, 0x2b, 0x02, 0xd1, 0x80, 0x23, + 0xdb, 0x01, 0x1d, 0x43, 0x00, 0x2f, 0x00, 0xd0, 0x2d, 0x04, 0x28, 0x00, + 0xf8, 0xbd, 0x83, 0x68, 0x70, 0xb5, 0x04, 0x00, 0x1d, 0x68, 0x00, 0x29, + 0x00, 0xd0, 0x2d, 0x0c, 0x63, 0x78, 0xad, 0x05, 0xad, 0x0d, 0x00, 0x2b, + 0x09, 0xd1, 0xa3, 0x8a, 0xeb, 0x18, 0xa3, 0x82, 0xa3, 0x8b, 0xab, 0x42, + 0x01, 0xd9, 0x00, 0x23, 0x63, 0x82, 0x28, 0x00, 0x70, 0xbd, 0xe3, 0x68, + 0x89, 0x01, 0x59, 0x18, 0x2a, 0x00, 0xa0, 0x69, 0xfd, 0xf7, 0x52, 0xfe, + 0xa3, 0x8a, 0xeb, 0x18, 0xa3, 0x82, 0xa3, 0x69, 0x5b, 0x19, 0xa3, 0x61, + 0xea, 0xe7, 0x00, 0x00, 0x80, 0x23, 0x0d, 0x4a, 0x5b, 0x04, 0x70, 0xb5, + 0x13, 0x60, 0x0c, 0x4a, 0x0c, 0x49, 0x13, 0x60, 0x1c, 0x00, 0x8a, 0x68, + 0x94, 0x43, 0xfb, 0xd1, 0x0a, 0x4d, 0x21, 0x00, 0x28, 0x00, 0x9c, 0x22, + 0xfd, 0xf7, 0x32, 0xfe, 0x80, 0x22, 0x21, 0x00, 0x52, 0x01, 0x07, 0x48, + 0xfd, 0xf7, 0x2c, 0xfe, 0x09, 0x23, 0x6b, 0x67, 0x70, 0xbd, 0xc0, 0x46, + 0x00, 0xe0, 0x00, 0x40, 0x00, 0xf0, 0x00, 0x40, 0x00, 0xc0, 0x00, 0x40, + 0x00, 0x00, 0x11, 0x50, 0x00, 0x00, 0x10, 0x50, 0x00, 0x23, 0x03, 0x74, + 0x43, 0x82, 0x83, 0x82, 0x83, 0x61, 0x70, 0x47, 0x10, 0xb5, 0x83, 0x68, + 0x00, 0x29, 0x01, 0xd0, 0x1c, 0x68, 0x21, 0x40, 0x00, 0x2a, 0x1a, 0xd0, + 0x80, 0x24, 0xe4, 0x00, 0x11, 0x43, 0x22, 0x42, 0x15, 0xd0, 0x1a, 0x68, + 0x22, 0x42, 0x09, 0xd0, 0x7f, 0x22, 0x81, 0x78, 0x09, 0x48, 0xcb, 0x09, + 0x11, 0x40, 0x09, 0x4a, 0x9b, 0x00, 0x9a, 0x58, 0xfc, 0xf7, 0xc2, 0xfe, + 0x07, 0x4a, 0x0a, 0x40, 0x1a, 0x60, 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, + 0xff, 0xe7, 0xff, 0xe7, 0xff, 0xe7, 0x83, 0x68, 0x19, 0x60, 0x10, 0xbd, + 0xe8, 0x00, 0x01, 0x10, 0x94, 0x05, 0x00, 0x20, 0xff, 0xfb, 0xff, 0xff, + 0x43, 0x68, 0x70, 0xb5, 0x00, 0x21, 0x80, 0x25, 0x1e, 0x68, 0x04, 0x00, + 0xff, 0xf7, 0x48, 0xff, 0x13, 0x4b, 0x6d, 0x01, 0x1a, 0x6c, 0x05, 0x43, + 0x00, 0x23, 0x92, 0x07, 0x03, 0xd4, 0xa2, 0x78, 0x01, 0x33, 0xd2, 0x09, + 0x9b, 0x1a, 0x62, 0x8a, 0x00, 0x2a, 0x13, 0xd0, 0x00, 0x2b, 0x11, 0xd1, + 0x01, 0x21, 0x20, 0x00, 0xff, 0xf7, 0x34, 0xff, 0x0a, 0x4b, 0x05, 0x43, + 0x1e, 0x40, 0xa0, 0x23, 0xdb, 0x05, 0x62, 0x68, 0x33, 0x43, 0x13, 0x60, + 0x00, 0x21, 0x2a, 0x00, 0x20, 0x00, 0xff, 0xf7, 0xab, 0xff, 0x70, 0xbd, + 0x04, 0x4b, 0x1e, 0x40, 0x80, 0x23, 0x9b, 0x05, 0xf1, 0xe7, 0xc0, 0x46, + 0x00, 0x00, 0x11, 0x50, 0xff, 0xff, 0xff, 0xdf, 0xff, 0xff, 0xff, 0xaf, + 0x00, 0x23, 0x10, 0xb5, 0x83, 0x82, 0x01, 0x33, 0x42, 0x82, 0x03, 0x74, + 0x81, 0x61, 0xff, 0xf7, 0xc1, 0xff, 0x10, 0xbd, 0x70, 0xb5, 0x05, 0x7c, + 0x04, 0x00, 0x00, 0x2d, 0x06, 0xd1, 0x7f, 0x23, 0x81, 0x78, 0x0f, 0x4a, + 0x0f, 0x48, 0x19, 0x40, 0xfc, 0xf7, 0x64, 0xfe, 0x83, 0x68, 0x00, 0x21, + 0x1b, 0x68, 0xff, 0xf7, 0x32, 0xff, 0x63, 0x68, 0x1b, 0x68, 0x5b, 0x00, + 0x06, 0xd5, 0xa3, 0x8b, 0x83, 0x42, 0x03, 0xd1, 0x01, 0x21, 0x20, 0x00, + 0xff, 0xf7, 0x27, 0xff, 0x63, 0x8a, 0x00, 0x2b, 0x03, 0xd0, 0x20, 0x00, + 0xff, 0xf7, 0x9e, 0xff, 0x00, 0x25, 0x28, 0x00, 0x70, 0xbd, 0xc0, 0x46, + 0x94, 0x05, 0x00, 0x20, 0x07, 0x01, 0x01, 0x10, 0x10, 0xb5, 0x00, 0xf0, + 0x03, 0xf8, 0x10, 0xb5, 0x00, 0xf0, 0x00, 0xf8, 0x06, 0x20, 0x10, 0xb5, + 0x01, 0xf0, 0x1b, 0xfc, 0x01, 0x20, 0xfc, 0xf7, 0x05, 0xfe, 0x70, 0xb5, + 0x0d, 0x00, 0x04, 0x00, 0xfa, 0xf7, 0x38, 0xff, 0x2a, 0x00, 0x21, 0x00, + 0x00, 0xf0, 0x01, 0xf8, 0x70, 0xbd, 0xf8, 0xb5, 0x00, 0x25, 0x0e, 0x00, + 0x0c, 0x0c, 0x13, 0x0c, 0xac, 0x42, 0x32, 0xd1, 0xab, 0x42, 0x21, 0xd1, + 0xb6, 0xb2, 0x91, 0xb2, 0x71, 0x43, 0x00, 0xf0, 0xad, 0xf9, 0x04, 0x1e, + 0x32, 0xd0, 0x03, 0x00, 0x08, 0x3b, 0x5a, 0x68, 0x03, 0x23, 0x9a, 0x43, + 0x04, 0x3a, 0x24, 0x2a, 0x31, 0xd8, 0x03, 0x00, 0x13, 0x2a, 0x0a, 0xd9, + 0x05, 0x60, 0x45, 0x60, 0x08, 0x33, 0x1b, 0x2a, 0x05, 0xd9, 0x85, 0x60, + 0xc5, 0x60, 0x24, 0x2a, 0x20, 0xd0, 0x03, 0x00, 0x10, 0x33, 0x00, 0x22, + 0x1a, 0x60, 0x5a, 0x60, 0x9a, 0x60, 0x17, 0xe0, 0x1c, 0x1c, 0xb1, 0xb2, + 0xb6, 0xb2, 0x92, 0xb2, 0x72, 0x43, 0xa3, 0xb2, 0x4b, 0x43, 0x11, 0x0c, + 0x5b, 0x18, 0x19, 0x0c, 0x07, 0xd1, 0x19, 0x04, 0x92, 0xb2, 0x11, 0x43, + 0xd1, 0xe7, 0x00, 0x2b, 0x01, 0xd1, 0x91, 0xb2, 0xee, 0xe7, 0x00, 0xf0, + 0x0e, 0xf8, 0x0c, 0x23, 0x00, 0x24, 0x03, 0x60, 0x20, 0x00, 0xf8, 0xbd, + 0x03, 0x00, 0x05, 0x61, 0x18, 0x33, 0x45, 0x61, 0xdb, 0xe7, 0x00, 0x21, + 0xfd, 0xf7, 0x1e, 0xfd, 0xf4, 0xe7, 0x10, 0xb5, 0xfa, 0xf7, 0xe2, 0xfe, + 0x10, 0xbd, 0x00, 0x00, 0x00, 0x23, 0x10, 0xb5, 0x04, 0x00, 0x03, 0x60, + 0x43, 0x60, 0x83, 0x60, 0x81, 0x81, 0x83, 0x66, 0x19, 0x00, 0xc2, 0x81, + 0x03, 0x61, 0x43, 0x61, 0x83, 0x61, 0x08, 0x22, 0x60, 0x30, 0xfd, 0xf7, + 0x07, 0xfd, 0x05, 0x4b, 0x24, 0x62, 0x63, 0x62, 0x04, 0x4b, 0xa3, 0x62, + 0x04, 0x4b, 0xe3, 0x62, 0x04, 0x4b, 0x23, 0x63, 0x10, 0xbd, 0xc0, 0x46, + 0x1d, 0xb3, 0x00, 0x10, 0x49, 0xb3, 0x00, 0x10, 0x81, 0xb3, 0x00, 0x10, + 0xad, 0xb3, 0x00, 0x10, 0x10, 0xb5, 0x02, 0x49, 0x00, 0xf0, 0x0f, 0xf9, + 0x10, 0xbd, 0xc0, 0x46, 0x6d, 0xd1, 0x00, 0x10, 0x83, 0x6e, 0x10, 0xb5, + 0xdb, 0x07, 0x05, 0xd4, 0x83, 0x89, 0x9b, 0x05, 0x02, 0xd4, 0x58, 0x30, + 0x05, 0xf0, 0xb5, 0xff, 0x00, 0x20, 0x10, 0xbd, 0x83, 0x6e, 0x10, 0xb5, + 0xdb, 0x07, 0x05, 0xd4, 0x83, 0x89, 0x9b, 0x05, 0x02, 0xd4, 0x58, 0x30, + 0x05, 0xf0, 0xad, 0xff, 0x00, 0x20, 0x10, 0xbd, 0x70, 0xb5, 0x70, 0x25, + 0x4a, 0x1e, 0x55, 0x43, 0x0e, 0x00, 0x29, 0x00, 0x80, 0x31, 0x00, 0xf0, + 0x1b, 0xf9, 0x04, 0x1e, 0x08, 0xd0, 0x00, 0x21, 0x2a, 0x00, 0x01, 0x60, + 0x46, 0x60, 0x10, 0x30, 0xa0, 0x60, 0x70, 0x32, 0xfd, 0xf7, 0xc0, 0xfc, + 0x20, 0x00, 0x70, 0xbd, 0x10, 0xb5, 0x02, 0x4b, 0x18, 0x68, 0xff, 0xf7, + 0xc5, 0xff, 0x10, 0xbd, 0x98, 0x01, 0x01, 0x10, 0x10, 0xb5, 0x02, 0x48, + 0x05, 0xf0, 0x85, 0xff, 0x10, 0xbd, 0xc0, 0x46, 0x50, 0x0c, 0x00, 0x20, + 0x10, 0xb5, 0x02, 0x48, 0x05, 0xf0, 0x81, 0xff, 0x10, 0xbd, 0xc0, 0x46, + 0x50, 0x0c, 0x00, 0x20, 0x10, 0xb5, 0x02, 0x48, 0x05, 0xf0, 0x75, 0xff, + 0x10, 0xbd, 0xc0, 0x46, 0x58, 0x0c, 0x00, 0x20, 0x10, 0xb5, 0x02, 0x48, + 0x05, 0xf0, 0x71, 0xff, 0x10, 0xbd, 0xc0, 0x46, 0x58, 0x0c, 0x00, 0x20, + 0x13, 0xb5, 0x04, 0x00, 0xff, 0xf7, 0xec, 0xff, 0xa3, 0x69, 0x00, 0x2b, + 0x02, 0xd0, 0xff, 0xf7, 0xef, 0xff, 0x13, 0xbd, 0x15, 0x4a, 0xa2, 0x62, + 0x22, 0x00, 0xd8, 0x32, 0x13, 0x60, 0x53, 0x60, 0x93, 0x60, 0x13, 0x4b, + 0x1b, 0x68, 0x01, 0x93, 0xa3, 0x42, 0x01, 0xd1, 0x01, 0x23, 0xa3, 0x61, + 0x20, 0x00, 0x00, 0xf0, 0x1f, 0xf8, 0x60, 0x60, 0x20, 0x00, 0x00, 0xf0, + 0x1b, 0xf8, 0xa0, 0x60, 0x20, 0x00, 0x00, 0xf0, 0x17, 0xf8, 0x00, 0x22, + 0x04, 0x21, 0xe0, 0x60, 0x60, 0x68, 0xff, 0xf7, 0x55, 0xff, 0x01, 0x22, + 0x09, 0x21, 0xa0, 0x68, 0xff, 0xf7, 0x50, 0xff, 0x02, 0x22, 0x12, 0x21, + 0xe0, 0x68, 0xff, 0xf7, 0x4b, 0xff, 0x01, 0x23, 0xa3, 0x61, 0xd0, 0xe7, + 0x09, 0x9b, 0x00, 0x10, 0x98, 0x01, 0x01, 0x10, 0xf8, 0xb5, 0x07, 0x00, + 0xff, 0xf7, 0xa2, 0xff, 0x1f, 0x4b, 0x1e, 0x68, 0xb3, 0x69, 0x00, 0x2b, + 0x02, 0xd1, 0x30, 0x00, 0xff, 0xf7, 0xba, 0xff, 0xd8, 0x36, 0xb4, 0x68, + 0x73, 0x68, 0x01, 0x3b, 0x04, 0xd5, 0x33, 0x68, 0x00, 0x2b, 0x22, 0xd0, + 0x36, 0x68, 0xf6, 0xe7, 0x0c, 0x22, 0xa5, 0x5e, 0x00, 0x2d, 0x1a, 0xd1, + 0x20, 0x00, 0x15, 0x4b, 0x58, 0x30, 0xe3, 0x60, 0xa5, 0x66, 0x05, 0xf0, + 0x09, 0xff, 0xff, 0xf7, 0x8b, 0xff, 0x20, 0x00, 0x08, 0x22, 0x29, 0x00, + 0x25, 0x60, 0xa5, 0x60, 0x65, 0x60, 0x25, 0x61, 0x65, 0x61, 0xa5, 0x61, + 0x60, 0x30, 0xfd, 0xf7, 0x2d, 0xfc, 0x65, 0x63, 0xa5, 0x63, 0xa5, 0x64, + 0xe5, 0x64, 0x20, 0x00, 0xf8, 0xbd, 0x70, 0x34, 0xd7, 0xe7, 0x04, 0x21, + 0x38, 0x00, 0xff, 0xf7, 0x4d, 0xff, 0x04, 0x1e, 0x30, 0x60, 0xd5, 0xd1, + 0xff, 0xf7, 0x6e, 0xff, 0x0c, 0x23, 0x3b, 0x60, 0xef, 0xe7, 0xc0, 0x46, + 0x98, 0x01, 0x01, 0x10, 0x01, 0x00, 0xff, 0xff, 0x10, 0xb5, 0xff, 0xf7, + 0x5b, 0xff, 0xfa, 0xf7, 0xd7, 0xfd, 0x02, 0x49, 0x00, 0xf0, 0x10, 0xf8, + 0x10, 0xbd, 0xc0, 0x46, 0x19, 0x9b, 0x00, 0x10, 0x10, 0xb5, 0xfa, 0xf7, + 0xcd, 0xfd, 0x03, 0x49, 0x00, 0xf0, 0x06, 0xf8, 0xff, 0xf7, 0x52, 0xff, + 0x10, 0xbd, 0xc0, 0x46, 0x31, 0x9b, 0x00, 0x10, 0xf7, 0xb5, 0xd8, 0x30, + 0x04, 0x00, 0x00, 0x26, 0x01, 0x91, 0xa5, 0x68, 0x67, 0x68, 0x01, 0x3f, + 0x04, 0xd5, 0x24, 0x68, 0x00, 0x2c, 0xf8, 0xd1, 0x30, 0x00, 0xfe, 0xbd, + 0xab, 0x89, 0x01, 0x2b, 0x07, 0xd9, 0x0e, 0x22, 0xab, 0x5e, 0x01, 0x33, + 0x03, 0xd0, 0x28, 0x00, 0x01, 0x9b, 0x98, 0x47, 0x06, 0x43, 0x70, 0x35, + 0xeb, 0xe7, 0xf7, 0xb5, 0x04, 0x00, 0x06, 0x00, 0x00, 0x27, 0x01, 0x91, + 0xd8, 0x34, 0x63, 0x68, 0xa5, 0x68, 0x00, 0x93, 0x00, 0x9b, 0x01, 0x3b, + 0x00, 0x93, 0x04, 0xd5, 0x24, 0x68, 0x00, 0x2c, 0xf5, 0xd1, 0x38, 0x00, + 0xfe, 0xbd, 0xab, 0x89, 0x01, 0x2b, 0x08, 0xd9, 0x0e, 0x22, 0xab, 0x5e, + 0x01, 0x33, 0x04, 0xd0, 0x29, 0x00, 0x30, 0x00, 0x01, 0x9b, 0x98, 0x47, + 0x07, 0x43, 0x70, 0x35, 0xe8, 0xe7, 0x10, 0xb5, 0x04, 0x00, 0xfa, 0xf7, + 0x85, 0xfd, 0x21, 0x00, 0x00, 0xf0, 0x0a, 0xf8, 0x10, 0xbd, 0x10, 0xb5, + 0x04, 0x00, 0xfa, 0xf7, 0x7d, 0xfd, 0x21, 0x00, 0x03, 0xf0, 0xac, 0xfb, + 0x10, 0xbd, 0x00, 0x00, 0x0b, 0x00, 0xf0, 0xb5, 0x0b, 0x33, 0x85, 0xb0, + 0x01, 0x90, 0x16, 0x2b, 0x09, 0xd9, 0x07, 0x22, 0x93, 0x43, 0x00, 0x93, + 0x07, 0xd5, 0x0c, 0x23, 0x01, 0x9a, 0x13, 0x60, 0x00, 0x20, 0x05, 0xb0, + 0xf0, 0xbd, 0x10, 0x23, 0x00, 0x93, 0x00, 0x9b, 0x99, 0x42, 0xf4, 0xd8, + 0x01, 0x98, 0x00, 0xf0, 0xf7, 0xf9, 0xfc, 0x23, 0x00, 0x99, 0xbd, 0x4a, + 0x5b, 0x00, 0x99, 0x42, 0x19, 0xd2, 0xcf, 0x08, 0x08, 0x31, 0x51, 0x18, + 0x08, 0x00, 0x4c, 0x68, 0x08, 0x38, 0x84, 0x42, 0x03, 0xd1, 0xcc, 0x68, + 0x02, 0x37, 0xa1, 0x42, 0x25, 0xd0, 0x03, 0x23, 0x62, 0x68, 0xa1, 0x68, + 0x9a, 0x43, 0x13, 0x00, 0xe2, 0x68, 0xca, 0x60, 0x91, 0x60, 0x01, 0x22, + 0xe3, 0x18, 0x59, 0x68, 0x0a, 0x43, 0x5a, 0x60, 0x56, 0xe0, 0x00, 0x9b, + 0x59, 0x0a, 0x3f, 0x23, 0x00, 0x29, 0x04, 0xd0, 0x04, 0x29, 0x29, 0xd8, + 0x00, 0x9b, 0x9b, 0x09, 0x38, 0x33, 0x03, 0x27, 0xd8, 0x00, 0x80, 0x18, + 0xc4, 0x68, 0x84, 0x42, 0x06, 0xd0, 0x61, 0x68, 0x00, 0x9d, 0xb9, 0x43, + 0x4e, 0x1b, 0x0f, 0x2e, 0x35, 0xdd, 0x01, 0x3b, 0x5f, 0x1c, 0x14, 0x69, + 0xa2, 0x49, 0x8c, 0x42, 0x5b, 0xd0, 0x03, 0x23, 0x60, 0x68, 0x98, 0x43, + 0x03, 0x00, 0x00, 0x98, 0x1d, 0x1a, 0x0f, 0x2d, 0x3a, 0xdd, 0x01, 0x26, + 0x00, 0x9f, 0x20, 0x18, 0x37, 0x43, 0x2e, 0x43, 0x67, 0x60, 0x50, 0x61, + 0x10, 0x61, 0xc1, 0x60, 0x81, 0x60, 0x46, 0x60, 0xe5, 0x50, 0x25, 0xe0, + 0x14, 0x29, 0x02, 0xd8, 0x0b, 0x00, 0x5b, 0x33, 0xd3, 0xe7, 0x54, 0x29, + 0x03, 0xd8, 0x00, 0x9b, 0x1b, 0x0b, 0x6e, 0x33, 0xcd, 0xe7, 0xaa, 0x23, + 0x5b, 0x00, 0x99, 0x42, 0x03, 0xd8, 0x00, 0x9b, 0xdb, 0x0b, 0x77, 0x33, + 0xc5, 0xe7, 0x8e, 0x48, 0x7e, 0x23, 0x81, 0x42, 0xc1, 0xd8, 0x00, 0x9b, + 0x9b, 0x0c, 0x7c, 0x33, 0xbd, 0xe7, 0xe5, 0x68, 0x00, 0x2e, 0x0d, 0xdb, + 0xa3, 0x68, 0x61, 0x18, 0xdd, 0x60, 0xab, 0x60, 0x01, 0x23, 0x4a, 0x68, + 0x13, 0x43, 0x4b, 0x60, 0x01, 0x98, 0x00, 0xf0, 0x85, 0xf9, 0x20, 0x00, + 0x08, 0x30, 0x78, 0xe7, 0x2c, 0x00, 0xae, 0xe7, 0x51, 0x61, 0x11, 0x61, + 0x00, 0x2d, 0x96, 0xda, 0x51, 0x68, 0x8c, 0x46, 0x80, 0x21, 0x89, 0x00, + 0x8b, 0x42, 0x00, 0xd3, 0x82, 0xe0, 0x58, 0x09, 0xd9, 0x08, 0x01, 0x23, + 0x83, 0x40, 0x60, 0x46, 0xc9, 0x00, 0x03, 0x43, 0x53, 0x60, 0x8a, 0x18, + 0x93, 0x68, 0xe2, 0x60, 0xa3, 0x60, 0x94, 0x60, 0xdc, 0x60, 0x01, 0x22, + 0x71, 0x49, 0xbb, 0x10, 0x48, 0x68, 0x9a, 0x40, 0x90, 0x42, 0x27, 0xd3, + 0x02, 0x42, 0x05, 0xd1, 0x03, 0x23, 0x9f, 0x43, 0x52, 0x00, 0x04, 0x37, + 0x02, 0x42, 0xfb, 0xd0, 0xfe, 0x00, 0x8e, 0x19, 0xb4, 0x46, 0x02, 0x97, + 0x63, 0x46, 0xdc, 0x68, 0x64, 0x45, 0x00, 0xd0, 0x93, 0xe0, 0x08, 0x23, + 0x03, 0x20, 0x9c, 0x44, 0x02, 0x9b, 0x01, 0x33, 0x02, 0x93, 0x03, 0x42, + 0xf2, 0xd1, 0x03, 0x23, 0x1f, 0x42, 0x00, 0xd0, 0xad, 0xe0, 0x4b, 0x68, + 0x93, 0x43, 0x4b, 0x60, 0x5e, 0x4b, 0x52, 0x00, 0x5b, 0x68, 0x93, 0x42, + 0x02, 0xd3, 0x00, 0x2a, 0x00, 0xd0, 0xae, 0xe0, 0x03, 0x23, 0x8e, 0x68, + 0x72, 0x68, 0x9a, 0x43, 0x13, 0x00, 0x02, 0x92, 0x00, 0x9a, 0x93, 0x42, + 0x03, 0xd3, 0x99, 0x1a, 0x0f, 0x29, 0x00, 0xdd, 0x11, 0xe1, 0x02, 0x9b, + 0x56, 0x4f, 0xf3, 0x18, 0x3a, 0x68, 0x03, 0x93, 0x00, 0x9b, 0x9d, 0x18, + 0x54, 0x4b, 0x1b, 0x68, 0x01, 0x33, 0x00, 0xd0, 0x97, 0xe0, 0x10, 0x35, + 0x29, 0x00, 0x01, 0x98, 0x01, 0xf0, 0xc4, 0xf8, 0x04, 0x00, 0x43, 0x1c, + 0x00, 0xd1, 0xd2, 0xe0, 0x03, 0x9b, 0x83, 0x42, 0x03, 0xd9, 0x48, 0x4b, + 0x9e, 0x42, 0x00, 0xd0, 0xcb, 0xe0, 0x7b, 0x68, 0xea, 0x18, 0x03, 0x9b, + 0x7a, 0x60, 0xa3, 0x42, 0x00, 0xd0, 0x91, 0xe0, 0x1b, 0x05, 0x00, 0xd0, + 0x8e, 0xe0, 0x41, 0x4b, 0x9a, 0x68, 0x02, 0x9b, 0x5d, 0x19, 0x01, 0x23, + 0x1d, 0x43, 0x55, 0x60, 0x40, 0x4b, 0x5a, 0x68, 0xd9, 0x6a, 0x8a, 0x42, + 0x00, 0xd9, 0xda, 0x62, 0x19, 0x6b, 0x8a, 0x42, 0x00, 0xd8, 0xb0, 0xe0, + 0x1a, 0x63, 0xae, 0xe0, 0x58, 0x0a, 0x04, 0x28, 0x12, 0xd8, 0x99, 0x09, + 0x38, 0x31, 0xcd, 0x00, 0xad, 0x18, 0xa8, 0x68, 0x03, 0x26, 0x85, 0x42, + 0x25, 0xd1, 0x01, 0x23, 0x89, 0x10, 0x8b, 0x40, 0x61, 0x46, 0x0b, 0x43, + 0x53, 0x60, 0xe5, 0x60, 0xa0, 0x60, 0xac, 0x60, 0xc4, 0x60, 0x74, 0xe7, + 0x14, 0x28, 0x02, 0xd8, 0x01, 0x00, 0x5b, 0x31, 0xe9, 0xe7, 0x54, 0x28, + 0x02, 0xd8, 0x19, 0x0b, 0x6e, 0x31, 0xe4, 0xe7, 0xaa, 0x21, 0x49, 0x00, + 0x88, 0x42, 0x02, 0xd8, 0xd9, 0x0b, 0x77, 0x31, 0xdd, 0xe7, 0x26, 0x4d, + 0x7e, 0x21, 0xa8, 0x42, 0xd9, 0xd8, 0x99, 0x0c, 0x7c, 0x31, 0xd6, 0xe7, + 0x80, 0x68, 0x85, 0x42, 0x03, 0xd0, 0x42, 0x68, 0xb2, 0x43, 0x9a, 0x42, + 0xf8, 0xd8, 0xc5, 0x68, 0xd9, 0xe7, 0x03, 0x20, 0x63, 0x68, 0x83, 0x43, + 0x00, 0x98, 0x1d, 0x1a, 0xe0, 0x68, 0x0f, 0x2d, 0x10, 0xdd, 0x01, 0x26, + 0x00, 0x9f, 0x00, 0x9a, 0x37, 0x43, 0x67, 0x60, 0xa7, 0x68, 0xa2, 0x18, + 0xf8, 0x60, 0x87, 0x60, 0x4a, 0x61, 0x0a, 0x61, 0x13, 0x49, 0x2e, 0x43, + 0xd1, 0x60, 0x91, 0x60, 0x56, 0x60, 0xf1, 0xe6, 0x00, 0x2d, 0x08, 0xdb, + 0x01, 0x22, 0xe3, 0x18, 0x59, 0x68, 0x0a, 0x43, 0x5a, 0x60, 0xa3, 0x68, + 0xd8, 0x60, 0x83, 0x60, 0x0e, 0xe7, 0x04, 0x00, 0x42, 0xe7, 0x33, 0x68, + 0x08, 0x3e, 0x01, 0x3f, 0xb3, 0x42, 0x00, 0xd1, 0x47, 0xe7, 0x4d, 0xe7, + 0x04, 0x37, 0x52, 0x00, 0x1a, 0x42, 0xfb, 0xd0, 0x30, 0xe7, 0x02, 0x9f, + 0xfa, 0xe7, 0x07, 0x4b, 0xed, 0x18, 0x2d, 0x0b, 0x2d, 0x03, 0x63, 0xe7, + 0x98, 0x06, 0x00, 0x20, 0xa0, 0x06, 0x00, 0x20, 0x54, 0x05, 0x00, 0x00, + 0xec, 0x0d, 0x00, 0x20, 0x90, 0x06, 0x00, 0x20, 0x0f, 0x10, 0x00, 0x00, + 0x33, 0x4b, 0x19, 0x68, 0x01, 0x31, 0x3d, 0xd1, 0x1c, 0x60, 0x07, 0x22, + 0x27, 0x00, 0x00, 0x23, 0x17, 0x40, 0x14, 0x42, 0x02, 0xd0, 0x08, 0x33, + 0xdb, 0x1b, 0xe4, 0x18, 0x62, 0x19, 0x9d, 0x1a, 0x2d, 0x05, 0x2d, 0x0d, + 0x29, 0x00, 0x01, 0x98, 0x03, 0x92, 0x01, 0xf0, 0x09, 0xf8, 0x43, 0x1c, + 0x07, 0xd1, 0x3d, 0x1e, 0x03, 0x98, 0x04, 0xd0, 0x38, 0x00, 0x00, 0x25, + 0x03, 0x9b, 0x08, 0x38, 0x18, 0x18, 0x24, 0x4a, 0x00, 0x1b, 0x53, 0x68, + 0x5b, 0x19, 0x53, 0x60, 0x01, 0x22, 0x22, 0x4b, 0x45, 0x19, 0x15, 0x43, + 0x9c, 0x60, 0x65, 0x60, 0x9e, 0x42, 0x00, 0xd1, 0x48, 0xe7, 0x02, 0x9b, + 0x0f, 0x2b, 0x15, 0xd8, 0x62, 0x60, 0x03, 0x22, 0x1b, 0x4b, 0x9b, 0x68, + 0x5b, 0x68, 0x93, 0x43, 0x00, 0x9a, 0x99, 0x1a, 0x93, 0x42, 0x01, 0xd3, + 0x0f, 0x29, 0x1e, 0xdc, 0x01, 0x98, 0x00, 0xf0, 0x35, 0xf8, 0x29, 0xe6, + 0x03, 0x9b, 0xe3, 0x1a, 0x9b, 0x18, 0x12, 0x4a, 0x53, 0x60, 0xbc, 0xe7, + 0x07, 0x21, 0x02, 0x9b, 0x0c, 0x3b, 0x8b, 0x43, 0x71, 0x68, 0x0a, 0x40, + 0x05, 0x21, 0x1a, 0x43, 0x72, 0x60, 0xf2, 0x18, 0x51, 0x60, 0x91, 0x60, + 0x0f, 0x2b, 0x00, 0xd8, 0x20, 0xe7, 0x31, 0x00, 0x01, 0x98, 0x08, 0x31, + 0x03, 0xf0, 0xac, 0xf9, 0x1a, 0xe7, 0x01, 0x22, 0x06, 0x48, 0x00, 0x9b, + 0x84, 0x68, 0x13, 0x43, 0x63, 0x60, 0x00, 0x9b, 0xe3, 0x18, 0x83, 0x60, + 0x2c, 0xe6, 0xc0, 0x46, 0x90, 0x06, 0x00, 0x20, 0xec, 0x0d, 0x00, 0x20, + 0x98, 0x06, 0x00, 0x20, 0x10, 0xb5, 0x02, 0x48, 0x05, 0xf0, 0x6f, 0xfc, + 0x10, 0xbd, 0xc0, 0x46, 0x38, 0x0c, 0x00, 0x20, 0x10, 0xb5, 0x02, 0x48, + 0x05, 0xf0, 0x6b, 0xfc, 0x10, 0xbd, 0xc0, 0x46, 0x38, 0x0c, 0x00, 0x20, + 0xf0, 0xb5, 0x1e, 0x00, 0x00, 0x23, 0x14, 0x00, 0x8b, 0xb0, 0x9e, 0x42, + 0x04, 0xda, 0x80, 0x21, 0x09, 0x06, 0x73, 0x18, 0x1e, 0x00, 0x2d, 0x23, + 0x12, 0x9a, 0x14, 0x9f, 0x13, 0x70, 0x20, 0x23, 0x03, 0x22, 0x9f, 0x43, + 0x46, 0x2f, 0x07, 0xd0, 0x3b, 0x00, 0x45, 0x3b, 0x59, 0x42, 0x4b, 0x41, + 0x10, 0x99, 0x01, 0x3a, 0xcb, 0x18, 0x10, 0x93, 0x09, 0xab, 0x04, 0x93, + 0x08, 0xab, 0x03, 0x93, 0x13, 0x9b, 0x00, 0x92, 0x02, 0x93, 0x10, 0x9b, + 0x22, 0x00, 0x01, 0x93, 0x33, 0x00, 0x02, 0xf0, 0x8a, 0xf9, 0x05, 0x00, + 0x47, 0x2f, 0x02, 0xd1, 0x11, 0x9b, 0xdb, 0x07, 0x28, 0xd5, 0x10, 0x9b, + 0xeb, 0x18, 0x07, 0x93, 0x46, 0x2f, 0x14, 0xd1, 0x2b, 0x78, 0x30, 0x2b, + 0x0c, 0xd1, 0x00, 0x22, 0x00, 0x23, 0x20, 0x00, 0x31, 0x00, 0xfc, 0xf7, + 0x11, 0xfd, 0x00, 0x28, 0x04, 0xd1, 0x01, 0x23, 0x10, 0x9a, 0x9b, 0x1a, + 0x13, 0x9a, 0x13, 0x60, 0x13, 0x9b, 0x07, 0x9a, 0x1b, 0x68, 0xd3, 0x18, + 0x07, 0x93, 0x00, 0x22, 0x00, 0x23, 0x20, 0x00, 0x31, 0x00, 0xfc, 0xf7, + 0xff, 0xfc, 0x00, 0x28, 0x01, 0xd0, 0x07, 0x9b, 0x09, 0x93, 0x30, 0x22, + 0x09, 0x9b, 0x07, 0x99, 0x8b, 0x42, 0x06, 0xd3, 0x28, 0x00, 0x09, 0x9b, + 0x15, 0x9a, 0x5b, 0x1b, 0x13, 0x60, 0x0b, 0xb0, 0xf0, 0xbd, 0x59, 0x1c, + 0x09, 0x91, 0x1a, 0x70, 0xf0, 0xe7, 0xf0, 0xb5, 0x83, 0x1c, 0x87, 0xb0, + 0x03, 0x93, 0x05, 0x00, 0x0c, 0x00, 0x2b, 0x23, 0x02, 0x70, 0x00, 0x29, + 0x01, 0xda, 0x4c, 0x42, 0x02, 0x33, 0x6b, 0x70, 0x09, 0x2c, 0x31, 0xdd, + 0x0a, 0x27, 0x04, 0xab, 0xde, 0x1d, 0x20, 0x00, 0x39, 0x00, 0x01, 0x96, + 0xfc, 0xf7, 0xf6, 0xf9, 0x01, 0x3e, 0x30, 0x31, 0x20, 0x00, 0x31, 0x70, + 0x39, 0x00, 0x02, 0x94, 0xfc, 0xf7, 0xee, 0xf9, 0x02, 0x9b, 0x04, 0x00, + 0x63, 0x2b, 0xee, 0xdc, 0x01, 0x9b, 0x30, 0x34, 0x9a, 0x1e, 0x13, 0x00, + 0x03, 0x99, 0x14, 0x70, 0x04, 0xa8, 0x07, 0x30, 0x98, 0x42, 0x0e, 0xd8, + 0x04, 0xab, 0x07, 0x33, 0x00, 0x20, 0x9a, 0x42, 0x04, 0xd8, 0x04, 0xab, + 0x09, 0x30, 0xc0, 0x18, 0x01, 0x9b, 0xc0, 0x1a, 0x03, 0x9b, 0x18, 0x18, + 0x40, 0x1b, 0x07, 0xb0, 0xf0, 0xbd, 0x18, 0x78, 0x01, 0x33, 0x08, 0x70, + 0x01, 0x31, 0xe7, 0xe7, 0x30, 0x23, 0xe4, 0x18, 0xab, 0x70, 0x28, 0x1d, + 0xec, 0x70, 0xf1, 0xe7, 0xf0, 0xb5, 0x95, 0xb0, 0x0c, 0x00, 0x08, 0x92, + 0x1a, 0x9d, 0x09, 0x93, 0x07, 0x00, 0x03, 0xf0, 0x99, 0xfe, 0x03, 0x68, + 0x18, 0x00, 0x0b, 0x93, 0x01, 0xf0, 0x3c, 0xf8, 0x00, 0x23, 0x12, 0x93, + 0x23, 0x7e, 0x07, 0x22, 0x1e, 0x00, 0x23, 0x68, 0x0d, 0x90, 0x0c, 0x93, + 0x0c, 0x99, 0x2b, 0x68, 0xc9, 0x05, 0x47, 0xd5, 0x9b, 0x18, 0x93, 0x43, + 0x1a, 0x00, 0x08, 0x32, 0x2a, 0x60, 0x1a, 0x68, 0x5b, 0x68, 0xa2, 0x64, + 0xe3, 0x64, 0x01, 0x22, 0xa3, 0x6c, 0xe5, 0x6c, 0x0a, 0x93, 0x6b, 0x00, + 0x5b, 0x08, 0x0e, 0x93, 0x0a, 0x98, 0xa8, 0x4b, 0x0e, 0x99, 0x52, 0x42, + 0xfc, 0xf7, 0x97, 0xfc, 0x00, 0x28, 0x31, 0xd1, 0x01, 0x22, 0xa4, 0x4b, + 0x0a, 0x98, 0x0e, 0x99, 0x52, 0x42, 0xfc, 0xf7, 0x79, 0xfc, 0x00, 0x28, + 0x28, 0xd1, 0x00, 0x22, 0x00, 0x23, 0x29, 0x00, 0x0a, 0x98, 0xfc, 0xf7, + 0x6b, 0xfc, 0x00, 0x28, 0x03, 0xd0, 0x23, 0x00, 0x2d, 0x22, 0x43, 0x33, + 0x1a, 0x70, 0x9b, 0x4d, 0x47, 0x2e, 0x00, 0xd9, 0x9a, 0x4d, 0x03, 0x23, + 0x0c, 0x9a, 0x23, 0x61, 0x01, 0x33, 0x9a, 0x43, 0x00, 0x23, 0x22, 0x60, + 0x0a, 0x93, 0x09, 0x9b, 0x21, 0x00, 0x00, 0x93, 0x38, 0x00, 0x08, 0x9b, + 0x13, 0xaa, 0x00, 0xf0, 0xf3, 0xf9, 0x43, 0x1c, 0x00, 0xd0, 0x9e, 0xe0, + 0x01, 0x20, 0x40, 0x42, 0x15, 0xb0, 0xf0, 0xbd, 0x07, 0x33, 0xb6, 0xe7, + 0x0a, 0x9a, 0x2b, 0x00, 0x10, 0x00, 0x29, 0x00, 0xfc, 0xf7, 0x5d, 0xfc, + 0x00, 0x28, 0x0a, 0xd0, 0x00, 0x2d, 0x03, 0xda, 0x23, 0x00, 0x2d, 0x22, + 0x43, 0x33, 0x1a, 0x70, 0x87, 0x4d, 0x47, 0x2e, 0xd5, 0xd9, 0x87, 0x4d, + 0xd3, 0xe7, 0x20, 0x22, 0x31, 0x00, 0x63, 0x68, 0x91, 0x43, 0x0e, 0x91, + 0x5a, 0x1c, 0x47, 0xd1, 0x07, 0x33, 0x63, 0x60, 0x80, 0x23, 0x0c, 0x9a, + 0xdb, 0x00, 0x13, 0x43, 0x00, 0x22, 0x06, 0x92, 0x12, 0xaa, 0x05, 0x92, + 0x11, 0xaa, 0x03, 0x92, 0x23, 0x22, 0x08, 0xa9, 0x23, 0x60, 0x01, 0x93, + 0x63, 0x68, 0x52, 0x18, 0x02, 0x92, 0x00, 0x93, 0x38, 0x00, 0x2b, 0x00, + 0x0a, 0x9a, 0x04, 0x96, 0xff, 0xf7, 0xbe, 0xfe, 0x0e, 0x9b, 0x05, 0x00, + 0x11, 0x99, 0x47, 0x2b, 0x08, 0xd1, 0xcb, 0x1c, 0x02, 0xdb, 0x63, 0x68, + 0x99, 0x42, 0x46, 0xdd, 0x33, 0x00, 0x02, 0x3b, 0xdb, 0xb2, 0x1e, 0x00, + 0x65, 0x2e, 0x24, 0xd8, 0x20, 0x00, 0x32, 0x00, 0x01, 0x39, 0x50, 0x30, + 0x11, 0x91, 0xff, 0xf7, 0x0a, 0xff, 0x12, 0x9a, 0x0a, 0x90, 0x13, 0x18, + 0x23, 0x61, 0x01, 0x2a, 0x02, 0xdc, 0x22, 0x68, 0xd2, 0x07, 0x01, 0xd5, + 0x01, 0x33, 0x23, 0x61, 0x23, 0x23, 0x08, 0xaa, 0x9b, 0x18, 0x1b, 0x78, + 0x00, 0x2b, 0x00, 0xd1, 0x91, 0xe7, 0x23, 0x00, 0x2d, 0x22, 0x43, 0x33, + 0x1a, 0x70, 0x8c, 0xe7, 0x0e, 0x9a, 0x47, 0x2a, 0xb6, 0xd1, 0x00, 0x2b, + 0xb4, 0xd1, 0x01, 0x33, 0xb1, 0xe7, 0x66, 0x2e, 0x1b, 0xd1, 0x63, 0x68, + 0x00, 0x29, 0x0d, 0xdd, 0x21, 0x61, 0x00, 0x2b, 0x02, 0xd1, 0x22, 0x68, + 0xd2, 0x07, 0x02, 0xd5, 0x01, 0x33, 0x59, 0x18, 0x21, 0x61, 0x11, 0x9b, + 0xa3, 0x65, 0x00, 0x23, 0x0a, 0x93, 0xd9, 0xe7, 0x00, 0x2b, 0x03, 0xd1, + 0x01, 0x22, 0x21, 0x68, 0x11, 0x42, 0x00, 0xd0, 0x9a, 0x1c, 0x22, 0x61, + 0xf1, 0xe7, 0x67, 0x23, 0x1e, 0x00, 0x11, 0x9b, 0x12, 0x9a, 0x93, 0x42, + 0x06, 0xdb, 0x22, 0x68, 0x23, 0x61, 0xd2, 0x07, 0xe7, 0xd5, 0x01, 0x33, + 0x23, 0x61, 0xe4, 0xe7, 0x01, 0x21, 0x00, 0x2b, 0x01, 0xdc, 0x49, 0x18, + 0xc9, 0x1a, 0x52, 0x18, 0xe9, 0xe7, 0x22, 0x68, 0x53, 0x05, 0x08, 0xd4, + 0x23, 0x69, 0x2a, 0x00, 0x38, 0x00, 0x08, 0x99, 0x09, 0x9d, 0xa8, 0x47, + 0x43, 0x1c, 0x29, 0xd1, 0x54, 0xe7, 0x65, 0x2e, 0x00, 0xd8, 0xec, 0xe0, + 0xa0, 0x6c, 0xe1, 0x6c, 0x00, 0x22, 0x00, 0x23, 0xfc, 0xf7, 0x92, 0xfb, + 0x00, 0x28, 0x34, 0xd0, 0x01, 0x23, 0x38, 0x00, 0x37, 0x4a, 0x08, 0x99, + 0x09, 0x9d, 0xa8, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0x40, 0xe7, 0x11, 0x9b, + 0x12, 0x9a, 0x93, 0x42, 0x02, 0xdb, 0x23, 0x68, 0xdb, 0x07, 0x0d, 0xd5, + 0x09, 0x9d, 0x38, 0x00, 0x0d, 0x9b, 0x0b, 0x9a, 0x08, 0x99, 0xa8, 0x47, + 0x00, 0x25, 0x43, 0x1c, 0x00, 0xd1, 0x2f, 0xe7, 0x12, 0x9b, 0x01, 0x3b, + 0xab, 0x42, 0x0a, 0xdc, 0x23, 0x68, 0x9b, 0x07, 0x00, 0xd5, 0x14, 0xe1, + 0x13, 0x9b, 0xe0, 0x68, 0x98, 0x42, 0x00, 0xdb, 0x24, 0xe7, 0x18, 0x00, + 0x22, 0xe7, 0x22, 0x00, 0x01, 0x23, 0x38, 0x00, 0x08, 0x99, 0x09, 0x9e, + 0x1a, 0x32, 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0x16, 0xe7, 0x01, 0x35, + 0xe4, 0xe7, 0x11, 0x9b, 0x00, 0x2b, 0x3b, 0xdc, 0x01, 0x23, 0x38, 0x00, + 0x1b, 0x4a, 0x08, 0x99, 0x09, 0x9e, 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, + 0x08, 0xe7, 0x11, 0x9b, 0x12, 0x9a, 0x13, 0x43, 0x02, 0xd1, 0x23, 0x68, + 0xdb, 0x07, 0xd5, 0xd5, 0x0d, 0x9b, 0x38, 0x00, 0x0b, 0x9a, 0x08, 0x99, + 0x09, 0x9e, 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0xf8, 0xe6, 0x00, 0x23, + 0x0a, 0x93, 0x11, 0x9b, 0x0a, 0x9a, 0x5b, 0x42, 0x93, 0x42, 0x01, 0xdc, + 0x12, 0x9b, 0x92, 0xe7, 0x22, 0x00, 0x01, 0x23, 0x38, 0x00, 0x08, 0x99, + 0x09, 0x9e, 0x1a, 0x32, 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0xe5, 0xe6, + 0x0a, 0x9b, 0x01, 0x33, 0xea, 0xe7, 0xc0, 0x46, 0xff, 0xff, 0xef, 0x7f, + 0x9c, 0x01, 0x01, 0x10, 0xa0, 0x01, 0x01, 0x10, 0xa4, 0x01, 0x01, 0x10, + 0xa8, 0x01, 0x01, 0x10, 0xac, 0x01, 0x01, 0x10, 0x12, 0x9a, 0xa3, 0x6d, + 0x0a, 0x92, 0x9a, 0x42, 0x00, 0xdd, 0x0a, 0x93, 0x0a, 0x9b, 0x00, 0x2b, + 0x3d, 0xdc, 0x00, 0x23, 0x0e, 0x93, 0x0a, 0x9b, 0xdb, 0x43, 0xdb, 0x17, + 0x0f, 0x93, 0xa3, 0x6d, 0x0f, 0x9a, 0x0c, 0x93, 0x0a, 0x9b, 0x13, 0x40, + 0x0c, 0x9a, 0xd3, 0x1a, 0x0e, 0x9a, 0x93, 0x42, 0x36, 0xdc, 0x11, 0x9b, + 0x12, 0x9a, 0x93, 0x42, 0x40, 0xdb, 0x23, 0x68, 0xdb, 0x07, 0x3d, 0xd4, + 0x12, 0x9a, 0x0c, 0x9b, 0x11, 0x99, 0xd3, 0x1a, 0x52, 0x1a, 0x0a, 0x92, + 0x9a, 0x42, 0x00, 0xdd, 0x0a, 0x93, 0x0a, 0x9b, 0x00, 0x2b, 0x3a, 0xdc, + 0x0a, 0x9b, 0x00, 0x25, 0xdb, 0x43, 0xdb, 0x17, 0x0b, 0x93, 0x11, 0x9a, + 0x12, 0x9b, 0x0b, 0x99, 0x9b, 0x1a, 0x0a, 0x9a, 0x0a, 0x40, 0x9b, 0x1a, + 0xab, 0x42, 0x00, 0xdc, 0x6e, 0xe7, 0x22, 0x00, 0x01, 0x23, 0x38, 0x00, + 0x08, 0x99, 0x09, 0x9e, 0x1a, 0x32, 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, + 0x90, 0xe6, 0x01, 0x35, 0xe9, 0xe7, 0x0a, 0x9b, 0x2a, 0x00, 0x38, 0x00, + 0x08, 0x99, 0x09, 0x9e, 0xb0, 0x47, 0x43, 0x1c, 0xb9, 0xd1, 0x85, 0xe6, + 0x22, 0x00, 0x01, 0x23, 0x38, 0x00, 0x08, 0x99, 0x09, 0x9e, 0x1a, 0x32, + 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0x7b, 0xe6, 0x0e, 0x9b, 0x01, 0x33, + 0x0e, 0x93, 0xb0, 0xe7, 0x0d, 0x9b, 0x38, 0x00, 0x0b, 0x9a, 0x08, 0x99, + 0x09, 0x9e, 0xb0, 0x47, 0x43, 0x1c, 0xb9, 0xd1, 0x6e, 0xe6, 0x0c, 0x9b, + 0x38, 0x00, 0xea, 0x18, 0x08, 0x99, 0x0a, 0x9b, 0x09, 0x9d, 0xa8, 0x47, + 0x43, 0x1c, 0xbb, 0xd1, 0x64, 0xe6, 0x12, 0x9b, 0x01, 0x2b, 0x02, 0xdc, + 0x01, 0x23, 0x1a, 0x42, 0x38, 0xd0, 0x01, 0x23, 0x2a, 0x00, 0x38, 0x00, + 0x08, 0x99, 0x09, 0x9e, 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0x55, 0xe6, + 0x0d, 0x9b, 0x38, 0x00, 0x0b, 0x9a, 0x08, 0x99, 0x09, 0x9e, 0xb0, 0x47, + 0x43, 0x1c, 0x00, 0xd1, 0x4c, 0xe6, 0xa0, 0x6c, 0xe1, 0x6c, 0x00, 0x22, + 0x00, 0x23, 0xfc, 0xf7, 0x8d, 0xfa, 0x00, 0x28, 0x1c, 0xd1, 0x12, 0x9b, + 0x6a, 0x1c, 0x01, 0x3b, 0x38, 0x00, 0x08, 0x99, 0x09, 0x9d, 0xa8, 0x47, + 0x43, 0x1c, 0x0f, 0xd1, 0x3a, 0xe6, 0x22, 0x00, 0x01, 0x23, 0x38, 0x00, + 0x08, 0x99, 0x09, 0x9e, 0x1a, 0x32, 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, + 0x30, 0xe6, 0x01, 0x35, 0x12, 0x9b, 0x01, 0x3b, 0xab, 0x42, 0xf0, 0xdc, + 0x22, 0x00, 0x0a, 0x9b, 0x50, 0x32, 0xcb, 0xe6, 0x00, 0x25, 0xf5, 0xe7, + 0x2a, 0x00, 0xe1, 0xe7, 0x22, 0x00, 0x01, 0x23, 0x38, 0x00, 0x08, 0x99, + 0x09, 0x9e, 0x19, 0x32, 0xb0, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0x19, 0xe6, + 0x01, 0x35, 0xe3, 0x68, 0x13, 0x9a, 0x9b, 0x1a, 0xab, 0x42, 0xef, 0xdc, + 0xea, 0xe6, 0x00, 0x25, 0xf7, 0xe7, 0xc0, 0x46, 0xf7, 0xb5, 0x15, 0x00, + 0x01, 0x93, 0x8a, 0x68, 0x0b, 0x69, 0x0c, 0x00, 0x00, 0x90, 0x93, 0x42, + 0x00, 0xda, 0x13, 0x00, 0x22, 0x00, 0x2b, 0x60, 0x43, 0x32, 0x12, 0x78, + 0x00, 0x2a, 0x01, 0xd0, 0x01, 0x33, 0x2b, 0x60, 0x23, 0x68, 0x9b, 0x06, + 0x02, 0xd5, 0x2b, 0x68, 0x02, 0x33, 0x2b, 0x60, 0x22, 0x68, 0x06, 0x23, + 0x17, 0x00, 0x1f, 0x40, 0x1a, 0x42, 0x27, 0xd0, 0x23, 0x00, 0x43, 0x33, + 0x1b, 0x78, 0x5a, 0x1e, 0x93, 0x41, 0x22, 0x68, 0x92, 0x06, 0x30, 0xd4, + 0x22, 0x00, 0x01, 0x99, 0x00, 0x98, 0x08, 0x9e, 0x43, 0x32, 0xb0, 0x47, + 0x43, 0x1c, 0x25, 0xd0, 0x06, 0x23, 0x20, 0x68, 0x2a, 0x68, 0xe1, 0x68, + 0x00, 0x25, 0x03, 0x40, 0x04, 0x2b, 0x03, 0xd1, 0x8d, 0x1a, 0xeb, 0x43, + 0xdb, 0x17, 0x1d, 0x40, 0xa3, 0x68, 0x22, 0x69, 0x93, 0x42, 0x01, 0xdd, + 0x9b, 0x1a, 0xed, 0x18, 0x00, 0x27, 0xbd, 0x42, 0x20, 0xd1, 0x00, 0x20, + 0x10, 0xe0, 0x01, 0x37, 0xe3, 0x68, 0x2a, 0x68, 0x9b, 0x1a, 0xbb, 0x42, + 0xd2, 0xdd, 0x22, 0x00, 0x01, 0x23, 0x01, 0x99, 0x00, 0x98, 0x08, 0x9e, + 0x19, 0x32, 0xb0, 0x47, 0x43, 0x1c, 0xf0, 0xd1, 0x01, 0x20, 0x40, 0x42, + 0xfe, 0xbd, 0x30, 0x20, 0xe1, 0x18, 0x43, 0x31, 0x08, 0x70, 0x21, 0x00, + 0x5a, 0x1c, 0x45, 0x31, 0x09, 0x78, 0xa2, 0x18, 0x43, 0x32, 0x02, 0x33, + 0x11, 0x70, 0xc1, 0xe7, 0x22, 0x00, 0x01, 0x23, 0x01, 0x99, 0x00, 0x98, + 0x08, 0x9e, 0x1a, 0x32, 0xb0, 0x47, 0x43, 0x1c, 0xe6, 0xd0, 0x01, 0x37, + 0xd1, 0xe7, 0xf0, 0xb5, 0x8d, 0xb0, 0x07, 0x92, 0x0a, 0x00, 0x43, 0x32, + 0x08, 0x93, 0x06, 0x90, 0x05, 0x92, 0x0e, 0x00, 0x09, 0x7e, 0x12, 0x9b, + 0x78, 0x29, 0x0a, 0xd8, 0x62, 0x29, 0x0c, 0xd8, 0x53, 0x29, 0x00, 0xd1, + 0x48, 0xe1, 0x58, 0x29, 0x00, 0xd1, 0xe0, 0xe0, 0x00, 0x29, 0x00, 0xd1, + 0x3a, 0xe1, 0x37, 0x00, 0x42, 0x37, 0x39, 0x70, 0x22, 0xe0, 0x08, 0x00, + 0x63, 0x38, 0x15, 0x28, 0xf7, 0xd8, 0x05, 0xf0, 0xe3, 0xf9, 0x16, 0x00, + 0x1f, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0x1f, 0x00, + 0xf6, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0xf6, 0xff, 0x24, 0x01, 0x51, 0x00, + 0xf4, 0x00, 0xf6, 0xff, 0xf6, 0xff, 0x39, 0x01, 0xf6, 0xff, 0x51, 0x00, + 0xf6, 0xff, 0xf6, 0xff, 0xf8, 0x00, 0x37, 0x00, 0x1a, 0x68, 0x42, 0x37, + 0x11, 0x1d, 0x19, 0x60, 0x13, 0x68, 0x3b, 0x70, 0x01, 0x23, 0x27, 0xe1, + 0x31, 0x68, 0x1a, 0x68, 0x08, 0x06, 0x03, 0xd5, 0x11, 0x1d, 0x19, 0x60, + 0x13, 0x68, 0x05, 0xe0, 0x48, 0x06, 0x06, 0xd5, 0x11, 0x1d, 0x19, 0x60, + 0x00, 0x23, 0xd3, 0x5e, 0x1c, 0x00, 0xdd, 0x17, 0x10, 0xe0, 0x88, 0x05, + 0x04, 0xd5, 0x11, 0x1d, 0x19, 0x60, 0x00, 0x23, 0xd3, 0x56, 0xf5, 0xe7, + 0x09, 0x05, 0xe9, 0xd5, 0x07, 0x21, 0x07, 0x32, 0x8a, 0x43, 0x11, 0x00, + 0x14, 0x68, 0x55, 0x68, 0x08, 0x31, 0x19, 0x60, 0x00, 0x2d, 0x08, 0xda, + 0x22, 0x00, 0x2b, 0x00, 0x00, 0x25, 0x54, 0x42, 0x9d, 0x41, 0x33, 0x00, + 0x2d, 0x22, 0x43, 0x33, 0x1a, 0x70, 0x93, 0x4b, 0x04, 0x93, 0x0a, 0x23, + 0x03, 0x93, 0x16, 0xe0, 0x34, 0x68, 0x80, 0x20, 0x27, 0x00, 0x1a, 0x68, + 0x07, 0x40, 0x04, 0x42, 0x55, 0xd0, 0x00, 0x25, 0x10, 0x1d, 0x14, 0x68, + 0x18, 0x60, 0x08, 0x22, 0x8a, 0x4b, 0x03, 0x92, 0x04, 0x93, 0x6f, 0x29, + 0x01, 0xd0, 0x0a, 0x23, 0x03, 0x93, 0x33, 0x00, 0x00, 0x22, 0x43, 0x33, + 0x1a, 0x70, 0x73, 0x68, 0xb3, 0x60, 0x00, 0x2b, 0x03, 0xdb, 0x04, 0x22, + 0x31, 0x68, 0x91, 0x43, 0x31, 0x60, 0x22, 0x00, 0x2a, 0x43, 0x02, 0xd1, + 0x05, 0x9f, 0x00, 0x2b, 0x18, 0xd0, 0x03, 0x9b, 0x05, 0x9f, 0xdb, 0x17, + 0x09, 0x93, 0x20, 0x00, 0x29, 0x00, 0x03, 0x9a, 0x09, 0x9b, 0xfb, 0xf7, + 0xd1, 0xfe, 0x04, 0x9b, 0x01, 0x3f, 0x9b, 0x5c, 0x22, 0x00, 0x3b, 0x70, + 0x2b, 0x00, 0x0d, 0x00, 0x09, 0x99, 0x04, 0x00, 0x99, 0x42, 0x03, 0xd8, + 0xed, 0xd1, 0x03, 0x9b, 0x93, 0x42, 0xea, 0xd9, 0x03, 0x9b, 0x08, 0x2b, + 0x09, 0xd1, 0x33, 0x68, 0xdb, 0x07, 0x06, 0xd5, 0x73, 0x68, 0x32, 0x69, + 0x93, 0x42, 0x02, 0xdc, 0x30, 0x23, 0x01, 0x3f, 0x3b, 0x70, 0x05, 0x9b, + 0xdb, 0x1b, 0x33, 0x61, 0x08, 0x9b, 0x31, 0x00, 0x00, 0x93, 0x06, 0x98, + 0x07, 0x9b, 0x0b, 0xaa, 0xff, 0xf7, 0xc8, 0xfe, 0x43, 0x1c, 0x00, 0xd0, + 0xa1, 0xe0, 0x01, 0x20, 0x40, 0x42, 0x0d, 0xb0, 0xf0, 0xbd, 0x40, 0x25, + 0x20, 0x00, 0x28, 0x40, 0x2c, 0x42, 0x05, 0xd0, 0x10, 0x1d, 0x18, 0x60, + 0x13, 0x68, 0x3d, 0x00, 0x9c, 0xb2, 0xa2, 0xe7, 0xa5, 0x05, 0x05, 0xd5, + 0x14, 0x1d, 0x1c, 0x60, 0x13, 0x68, 0xdc, 0xb2, 0x05, 0x00, 0x9a, 0xe7, + 0x80, 0x25, 0x20, 0x00, 0x2d, 0x01, 0x28, 0x40, 0x2c, 0x42, 0x08, 0xd0, + 0x07, 0x20, 0x07, 0x32, 0x82, 0x43, 0x10, 0x00, 0x14, 0x68, 0x55, 0x68, + 0x08, 0x30, 0x18, 0x60, 0x8b, 0xe7, 0x14, 0x1d, 0x1c, 0x60, 0x14, 0x68, + 0xea, 0xe7, 0x32, 0x00, 0x45, 0x32, 0x11, 0x70, 0x4d, 0x4a, 0x31, 0x68, + 0x80, 0x20, 0x0f, 0x00, 0x04, 0x92, 0x07, 0x40, 0x1a, 0x68, 0x01, 0x42, + 0x1d, 0xd0, 0x00, 0x25, 0x10, 0x1d, 0x14, 0x68, 0x18, 0x60, 0xcb, 0x07, + 0x02, 0xd5, 0x20, 0x23, 0x19, 0x43, 0x31, 0x60, 0x10, 0x23, 0x03, 0x93, + 0x23, 0x00, 0x2b, 0x43, 0x00, 0xd0, 0x74, 0xe7, 0x32, 0x68, 0x20, 0x33, + 0x9a, 0x43, 0x32, 0x60, 0x6f, 0xe7, 0x20, 0x22, 0x31, 0x68, 0x0a, 0x43, + 0x32, 0x60, 0x32, 0x00, 0x78, 0x21, 0x45, 0x32, 0x11, 0x70, 0x3c, 0x4a, + 0xd9, 0xe7, 0x40, 0x24, 0x08, 0x00, 0x20, 0x40, 0x21, 0x42, 0x05, 0xd0, + 0x10, 0x1d, 0x18, 0x60, 0x13, 0x68, 0x9c, 0xb2, 0x3d, 0x00, 0xda, 0xe7, + 0x8c, 0x05, 0x05, 0xd5, 0x14, 0x1d, 0x1c, 0x60, 0x13, 0x68, 0x05, 0x00, + 0xdc, 0xb2, 0xd2, 0xe7, 0x80, 0x20, 0x0f, 0x00, 0x00, 0x01, 0x07, 0x40, + 0x01, 0x42, 0x08, 0xd0, 0x07, 0x20, 0x07, 0x32, 0x82, 0x43, 0x10, 0x00, + 0x14, 0x68, 0x55, 0x68, 0x08, 0x30, 0x18, 0x60, 0xc3, 0xe7, 0x10, 0x1d, + 0x14, 0x68, 0x18, 0x60, 0xe2, 0xe7, 0x1a, 0x68, 0x34, 0x68, 0x11, 0x1d, + 0x70, 0x69, 0x19, 0x60, 0x13, 0x68, 0x25, 0x06, 0x01, 0xd5, 0x18, 0x60, + 0x02, 0xe0, 0x65, 0x06, 0x04, 0xd5, 0x18, 0x80, 0x00, 0x23, 0x05, 0x9f, + 0x33, 0x61, 0x69, 0xe7, 0xa4, 0x05, 0xf4, 0xd5, 0x18, 0x70, 0xf7, 0xe7, + 0x1a, 0x68, 0x11, 0x1d, 0x19, 0x60, 0x17, 0x68, 0x00, 0x21, 0x38, 0x00, + 0x72, 0x68, 0x05, 0xf0, 0x71, 0xf8, 0x00, 0x28, 0x01, 0xd0, 0xc0, 0x1b, + 0x70, 0x60, 0x73, 0x68, 0x33, 0x61, 0x00, 0x23, 0x05, 0x9a, 0x13, 0x70, + 0x52, 0xe7, 0x33, 0x69, 0x3a, 0x00, 0x07, 0x99, 0x06, 0x98, 0x08, 0x9c, + 0xa0, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0x54, 0xe7, 0x33, 0x68, 0x9b, 0x07, + 0x17, 0xd4, 0x0b, 0x9b, 0xf0, 0x68, 0x98, 0x42, 0x00, 0xdb, 0x4e, 0xe7, + 0x18, 0x00, 0x4c, 0xe7, 0x32, 0x00, 0x01, 0x23, 0x07, 0x99, 0x06, 0x98, + 0x08, 0x9d, 0x19, 0x32, 0xa8, 0x47, 0x43, 0x1c, 0x00, 0xd1, 0x40, 0xe7, + 0x01, 0x34, 0xf3, 0x68, 0x0b, 0x9a, 0x9b, 0x1a, 0xa3, 0x42, 0xef, 0xdc, + 0xe7, 0xe7, 0x00, 0x24, 0xf7, 0xe7, 0xc0, 0x46, 0xae, 0x01, 0x01, 0x10, + 0xbf, 0x01, 0x01, 0x10, 0xf0, 0xb5, 0x8b, 0xb0, 0x15, 0x00, 0x01, 0x90, + 0xae, 0x22, 0x00, 0x20, 0x06, 0x93, 0x8b, 0x68, 0x0e, 0x00, 0x59, 0x1e, + 0x52, 0x00, 0x05, 0x90, 0x91, 0x42, 0x05, 0xd9, 0x5e, 0x3b, 0xff, 0x3b, + 0x05, 0x93, 0x5e, 0x23, 0xff, 0x33, 0xb3, 0x60, 0xf0, 0x23, 0x32, 0x68, + 0xdb, 0x00, 0x13, 0x43, 0x33, 0x60, 0x33, 0x00, 0x00, 0x24, 0x1c, 0x33, + 0x1f, 0x00, 0x03, 0x93, 0x02, 0x94, 0x08, 0x94, 0x07, 0x94, 0x00, 0x94, + 0x04, 0x94, 0xb2, 0x68, 0x00, 0x2a, 0x0a, 0xd0, 0x2b, 0x68, 0x1b, 0x78, + 0x4e, 0x2b, 0x44, 0xd8, 0x18, 0x00, 0x40, 0x2b, 0x2c, 0xd8, 0x2b, 0x38, + 0xc1, 0xb2, 0x0e, 0x29, 0x2a, 0xd9, 0x00, 0x9b, 0x00, 0x2b, 0x03, 0xd0, + 0x32, 0x68, 0xa4, 0x4b, 0x13, 0x40, 0x33, 0x60, 0x02, 0x9b, 0x01, 0x3b, + 0x01, 0x2b, 0x00, 0xd9, 0xf9, 0xe0, 0xbe, 0x24, 0x64, 0x00, 0x03, 0x9b, + 0x9f, 0x42, 0x00, 0xd9, 0xe9, 0xe0, 0x01, 0x23, 0x02, 0x93, 0x85, 0xe1, + 0x18, 0x00, 0x61, 0x38, 0x0d, 0x28, 0xe6, 0xd8, 0x05, 0xf0, 0x20, 0xf8, + 0x83, 0x00, 0xe5, 0xff, 0xe5, 0xff, 0xe5, 0xff, 0xb6, 0x00, 0xa2, 0x00, + 0xe5, 0xff, 0xe5, 0xff, 0x89, 0x00, 0xe5, 0xff, 0xe5, 0xff, 0xe5, 0xff, + 0xe5, 0xff, 0x65, 0x00, 0x41, 0x38, 0xeb, 0xe7, 0x0e, 0x28, 0xd2, 0xd8, + 0x05, 0xf0, 0x0c, 0xf8, 0x4b, 0x00, 0xd1, 0xff, 0x4b, 0x00, 0x98, 0x00, + 0xd1, 0xff, 0x20, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, + 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x6e, 0x2b, + 0x09, 0xd8, 0x60, 0x2b, 0xd2, 0xd8, 0x54, 0x2b, 0x7d, 0xd0, 0x59, 0x2b, + 0xb9, 0xd1, 0x07, 0x2c, 0xb7, 0xd1, 0x08, 0x24, 0x2c, 0xe0, 0x74, 0x2b, + 0x75, 0xd0, 0x79, 0x2b, 0xf7, 0xd0, 0xb0, 0xe7, 0x31, 0x68, 0xc8, 0x05, + 0x1c, 0xd5, 0x80, 0x23, 0x99, 0x43, 0x00, 0x9b, 0x31, 0x60, 0x01, 0x33, + 0x00, 0x93, 0x05, 0x9b, 0x00, 0x2b, 0x03, 0xd0, 0x01, 0x3b, 0x01, 0x32, + 0x05, 0x93, 0xb2, 0x60, 0xb3, 0x68, 0x01, 0x3b, 0xb3, 0x60, 0x33, 0x69, + 0x01, 0x33, 0x33, 0x61, 0x6b, 0x68, 0x01, 0x3b, 0x6b, 0x60, 0x00, 0x2b, + 0x00, 0xdc, 0x86, 0xe0, 0x2b, 0x68, 0x01, 0x33, 0x2b, 0x60, 0x82, 0xe7, + 0x02, 0x9a, 0x12, 0x19, 0x00, 0x2a, 0x8c, 0xd1, 0x6d, 0x4a, 0x31, 0x68, + 0x0a, 0x40, 0x32, 0x60, 0x3b, 0x70, 0x01, 0x37, 0xe4, 0xe7, 0x80, 0x21, + 0x32, 0x68, 0x0a, 0x42, 0x81, 0xd0, 0x8a, 0x43, 0xf5, 0xe7, 0x02, 0x9a, + 0x00, 0x2a, 0x0f, 0xd1, 0x00, 0x9a, 0x00, 0x2a, 0x0f, 0xd1, 0x32, 0x68, + 0xe0, 0x21, 0x10, 0x00, 0xc9, 0x00, 0x08, 0x40, 0x88, 0x42, 0x08, 0xd1, + 0x61, 0x49, 0x0a, 0x40, 0x32, 0x60, 0x01, 0x22, 0x02, 0x92, 0xe3, 0xe7, + 0x02, 0x9a, 0x02, 0x2a, 0x59, 0xd0, 0x01, 0x2c, 0x02, 0xd0, 0x04, 0x2c, + 0x00, 0xd0, 0x64, 0xe7, 0x01, 0x34, 0xe4, 0xb2, 0xd8, 0xe7, 0x02, 0x9a, + 0x01, 0x2a, 0x00, 0xd0, 0x5d, 0xe7, 0x02, 0x22, 0xec, 0xe7, 0x00, 0x2c, + 0x10, 0xd1, 0x00, 0x9a, 0x00, 0x2a, 0x00, 0xd0, 0x58, 0xe7, 0x32, 0x68, + 0xe0, 0x21, 0x10, 0x00, 0xc9, 0x00, 0x08, 0x40, 0x88, 0x42, 0x00, 0xd0, + 0x54, 0xe7, 0x4f, 0x49, 0x01, 0x34, 0x0a, 0x40, 0x32, 0x60, 0xbf, 0xe7, + 0xfd, 0x21, 0xe2, 0x1e, 0x0a, 0x42, 0x00, 0xd0, 0x43, 0xe7, 0xdd, 0xe7, + 0x02, 0x2c, 0x00, 0xd0, 0x3f, 0xe7, 0x03, 0x24, 0xb4, 0xe7, 0x06, 0x2c, + 0x00, 0xd0, 0x3a, 0xe7, 0x07, 0x24, 0xaf, 0xe7, 0x32, 0x68, 0x91, 0x05, + 0x00, 0xd4, 0x34, 0xe7, 0x43, 0x49, 0x0a, 0x40, 0x32, 0x60, 0x00, 0x9a, + 0x04, 0x92, 0xa5, 0xe7, 0xa0, 0x21, 0x80, 0x20, 0x32, 0x68, 0xc9, 0x00, + 0x11, 0x40, 0xc0, 0x00, 0x81, 0x42, 0x06, 0xd0, 0x02, 0x42, 0x00, 0xd1, + 0x23, 0xe7, 0x00, 0x99, 0x00, 0x29, 0x00, 0xd1, 0x26, 0xe7, 0x91, 0x05, + 0x04, 0xd4, 0x00, 0x99, 0x04, 0x98, 0x08, 0x97, 0x09, 0x1a, 0x07, 0x91, + 0x34, 0x49, 0x0a, 0x40, 0xc0, 0x21, 0x49, 0x00, 0x0a, 0x43, 0x32, 0x60, + 0x00, 0x22, 0x00, 0x92, 0x86, 0xe7, 0x03, 0x22, 0x9e, 0xe7, 0xc0, 0x23, + 0x5b, 0x00, 0x29, 0x00, 0xf3, 0x58, 0x01, 0x98, 0x98, 0x47, 0x00, 0x28, + 0x00, 0xd1, 0xf6, 0xe6, 0x03, 0xe7, 0x01, 0x3f, 0x33, 0x59, 0x2a, 0x00, + 0x39, 0x78, 0x01, 0x98, 0x98, 0x47, 0x33, 0x69, 0x01, 0x3b, 0x33, 0x61, + 0x07, 0xe7, 0x63, 0x1e, 0x06, 0x2b, 0x0e, 0xd8, 0x02, 0x97, 0x02, 0x2c, + 0x20, 0xd9, 0xe3, 0x1b, 0xdb, 0xb2, 0x05, 0x93, 0x02, 0x9b, 0x05, 0x9a, + 0x9b, 0x18, 0xdb, 0xb2, 0x03, 0x2b, 0x27, 0xd8, 0x03, 0x3c, 0xe4, 0xb2, + 0x3f, 0x1b, 0x33, 0x68, 0xda, 0x05, 0x54, 0xd5, 0x5b, 0x05, 0x37, 0xd5, + 0xbe, 0x24, 0x64, 0x00, 0x03, 0x9b, 0x9f, 0x42, 0x00, 0xd8, 0xee, 0xe6, + 0x01, 0x3f, 0x33, 0x59, 0x2a, 0x00, 0x39, 0x78, 0x01, 0x98, 0x98, 0x47, + 0x33, 0x69, 0x01, 0x3b, 0x33, 0x61, 0xf1, 0xe7, 0xbe, 0x24, 0x64, 0x00, + 0x03, 0x9b, 0x9f, 0x42, 0x00, 0xd8, 0xde, 0xe6, 0x01, 0x3f, 0x33, 0x59, + 0x2a, 0x00, 0x39, 0x78, 0x01, 0x98, 0x98, 0x47, 0x33, 0x69, 0x01, 0x3b, + 0x33, 0x61, 0xf1, 0xe7, 0x02, 0x9b, 0x2a, 0x00, 0x01, 0x3b, 0x19, 0x78, + 0x02, 0x93, 0xbe, 0x23, 0x5b, 0x00, 0xf3, 0x58, 0x01, 0x98, 0x09, 0x93, + 0x98, 0x47, 0x33, 0x69, 0x01, 0x3b, 0x33, 0x61, 0xc2, 0xe7, 0xc0, 0x46, + 0xff, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0xff, 0xff, 0x7f, 0xf8, 0xff, 0xff, + 0x7f, 0xfd, 0xff, 0xff, 0x33, 0x69, 0x7c, 0x1e, 0x21, 0x78, 0x01, 0x3b, + 0x33, 0x61, 0x65, 0x29, 0x0c, 0xd0, 0x45, 0x29, 0x0a, 0xd0, 0xbe, 0x23, + 0x5b, 0x00, 0xf3, 0x58, 0x2a, 0x00, 0x01, 0x98, 0x98, 0x47, 0x33, 0x69, + 0xbc, 0x1e, 0x01, 0x3b, 0x21, 0x78, 0x33, 0x61, 0xbe, 0x23, 0x5b, 0x00, + 0x2a, 0x00, 0xf3, 0x58, 0x01, 0x98, 0x98, 0x47, 0x27, 0x00, 0x32, 0x68, + 0x10, 0x23, 0x11, 0x00, 0x19, 0x40, 0x02, 0x91, 0x1a, 0x42, 0x58, 0xd1, + 0xc0, 0x23, 0x39, 0x70, 0x32, 0x68, 0xdb, 0x00, 0x13, 0x40, 0x80, 0x22, + 0xd2, 0x00, 0x93, 0x42, 0x1d, 0xd1, 0x04, 0x9b, 0x00, 0x9a, 0x00, 0x99, + 0x9a, 0x1a, 0x8b, 0x42, 0x24, 0xd1, 0x00, 0x22, 0x03, 0x99, 0x01, 0x98, + 0x01, 0xf0, 0x70, 0xf8, 0x06, 0x9b, 0x0d, 0x00, 0x31, 0x68, 0x04, 0x00, + 0x1b, 0x68, 0x8a, 0x07, 0x25, 0xd5, 0x1a, 0x1d, 0x06, 0x99, 0x0a, 0x60, + 0x1b, 0x68, 0x1c, 0x60, 0x5d, 0x60, 0xf3, 0x68, 0x01, 0x33, 0xf3, 0x60, + 0x02, 0x98, 0x0b, 0xb0, 0xf0, 0xbd, 0x07, 0x9b, 0x00, 0x2b, 0xe4, 0xd0, + 0x08, 0x9b, 0x02, 0x9a, 0x59, 0x1c, 0x01, 0x98, 0x0a, 0x23, 0x01, 0xf0, + 0xaf, 0xf9, 0x07, 0x9b, 0x08, 0x9f, 0xc2, 0x1a, 0x33, 0x00, 0x70, 0x33, + 0xff, 0x33, 0x9f, 0x42, 0x02, 0xd3, 0x37, 0x00, 0x6f, 0x37, 0xff, 0x37, + 0x38, 0x00, 0x0f, 0x49, 0x00, 0xf0, 0x9e, 0xf9, 0xcd, 0xe7, 0x1a, 0x1d, + 0x49, 0x07, 0xd7, 0xd4, 0x06, 0x99, 0x20, 0x00, 0x0a, 0x60, 0x1f, 0x68, + 0x22, 0x00, 0x2b, 0x00, 0x29, 0x00, 0xfb, 0xf7, 0x7c, 0xfe, 0x00, 0x28, + 0x04, 0xd0, 0x07, 0x48, 0x00, 0xf0, 0xba, 0xf8, 0x38, 0x60, 0xcc, 0xe7, + 0x20, 0x00, 0x29, 0x00, 0xfb, 0xf7, 0x04, 0xff, 0xf8, 0xe7, 0x00, 0x23, + 0x40, 0xe6, 0xc0, 0x46, 0xd0, 0x01, 0x01, 0x10, 0x11, 0xfd, 0x00, 0x10, + 0x0e, 0xb4, 0x17, 0xb5, 0x04, 0x1e, 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, + 0x01, 0xd1, 0xfe, 0xf7, 0xe9, 0xfd, 0x06, 0xab, 0x20, 0x00, 0x05, 0x9a, + 0xa1, 0x68, 0x01, 0x93, 0x03, 0xf0, 0xbe, 0xff, 0x1e, 0xbc, 0x08, 0xbc, + 0x03, 0xb0, 0x18, 0x47, 0x0f, 0xb4, 0x13, 0xb5, 0xf9, 0xf7, 0x38, 0xfc, + 0x04, 0x1e, 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, 0x01, 0xd1, 0xfe, 0xf7, + 0xd3, 0xfd, 0x05, 0xab, 0x20, 0x00, 0x04, 0x9a, 0xa1, 0x68, 0x01, 0x93, + 0x03, 0xf0, 0xa8, 0xff, 0x16, 0xbc, 0x08, 0xbc, 0x04, 0xb0, 0x18, 0x47, + 0x30, 0xb5, 0x05, 0x00, 0x89, 0xb0, 0x08, 0x00, 0x0c, 0x00, 0x00, 0xf0, + 0xbb, 0xf9, 0x2b, 0x4a, 0x04, 0xab, 0x06, 0x92, 0x01, 0x22, 0x01, 0x93, + 0x02, 0x23, 0x05, 0x90, 0x80, 0x18, 0x04, 0x94, 0x07, 0x92, 0x03, 0x90, + 0x02, 0x93, 0x00, 0x2d, 0x05, 0xd0, 0xab, 0x69, 0x00, 0x2b, 0x02, 0xd1, + 0x28, 0x00, 0xfe, 0xf7, 0xad, 0xfd, 0xab, 0x69, 0xac, 0x68, 0x00, 0x2b, + 0x02, 0xd1, 0x28, 0x00, 0xfe, 0xf7, 0xa6, 0xfd, 0x1e, 0x4b, 0x9c, 0x42, + 0x2d, 0xd1, 0x6c, 0x68, 0xa3, 0x6e, 0xdb, 0x07, 0x06, 0xd4, 0xa3, 0x89, + 0x9b, 0x05, 0x03, 0xd4, 0x20, 0x00, 0x58, 0x30, 0x04, 0xf0, 0x01, 0xfd, + 0x0c, 0x23, 0xe2, 0x5e, 0x80, 0x23, 0x9b, 0x01, 0x1a, 0x42, 0x05, 0xd1, + 0x13, 0x43, 0xa3, 0x81, 0xa2, 0x6e, 0x14, 0x4b, 0x13, 0x40, 0xa3, 0x66, + 0x28, 0x00, 0x21, 0x00, 0x01, 0xaa, 0x02, 0xf0, 0xc9, 0xfa, 0x0a, 0x25, + 0x00, 0x28, 0x01, 0xd0, 0x01, 0x25, 0x6d, 0x42, 0xa3, 0x6e, 0xdb, 0x07, + 0x06, 0xd4, 0xa3, 0x89, 0x9b, 0x05, 0x03, 0xd4, 0x20, 0x00, 0x58, 0x30, + 0x04, 0xf0, 0xe5, 0xfc, 0x28, 0x00, 0x09, 0xb0, 0x30, 0xbd, 0x08, 0x4b, + 0x9c, 0x42, 0x01, 0xd1, 0xac, 0x68, 0xcd, 0xe7, 0x06, 0x4b, 0x9c, 0x42, + 0xca, 0xd1, 0xec, 0x68, 0xc8, 0xe7, 0xc0, 0x46, 0x10, 0xfd, 0x00, 0x10, + 0x78, 0x01, 0x01, 0x10, 0xff, 0xdf, 0xff, 0xff, 0x58, 0x01, 0x01, 0x10, + 0x38, 0x01, 0x01, 0x10, 0x10, 0xb5, 0x04, 0x00, 0xf9, 0xf7, 0xba, 0xfb, + 0x21, 0x00, 0xff, 0xf7, 0x91, 0xff, 0x10, 0xbd, 0x00, 0x23, 0x70, 0xb5, + 0x06, 0x4d, 0x04, 0x00, 0x08, 0x00, 0x2b, 0x60, 0xfb, 0xf7, 0x78, 0xfa, + 0x43, 0x1c, 0x03, 0xd1, 0x2b, 0x68, 0x00, 0x2b, 0x00, 0xd0, 0x23, 0x60, + 0x70, 0xbd, 0xc0, 0x46, 0x20, 0x0e, 0x00, 0x20, 0x00, 0x48, 0x70, 0x47, + 0x00, 0x00, 0xc0, 0x7f, 0x70, 0xb5, 0x44, 0x6c, 0x05, 0x00, 0x00, 0x2c, + 0x0a, 0xd1, 0x80, 0x21, 0xfe, 0xf7, 0x20, 0xfe, 0x68, 0x64, 0x00, 0x28, + 0x06, 0xd0, 0x03, 0x00, 0x80, 0x33, 0x10, 0xc0, 0x98, 0x42, 0xfc, 0xd1, + 0x00, 0x20, 0x70, 0xbd, 0x01, 0x20, 0x40, 0x42, 0xfb, 0xe7, 0x70, 0xb5, + 0x04, 0x00, 0x0d, 0x00, 0x16, 0x00, 0x1f, 0x29, 0x04, 0xd9, 0x16, 0x23, + 0x03, 0x60, 0x01, 0x20, 0x40, 0x42, 0x07, 0xe0, 0x43, 0x6c, 0x00, 0x2b, + 0x05, 0xd0, 0xa9, 0x00, 0x65, 0x6c, 0x6d, 0x18, 0x28, 0x68, 0x2e, 0x60, + 0x70, 0xbd, 0xff, 0xf7, 0xd5, 0xff, 0x00, 0x28, 0xf5, 0xd0, 0xee, 0xe7, + 0x70, 0xb5, 0x04, 0x00, 0x0d, 0x00, 0x1f, 0x29, 0x04, 0xd9, 0x16, 0x23, + 0x03, 0x60, 0x01, 0x20, 0x40, 0x42, 0x70, 0xbd, 0x43, 0x6c, 0x00, 0x2b, + 0x04, 0xd0, 0x8a, 0x00, 0x9b, 0x18, 0x1a, 0x68, 0x00, 0x2a, 0x08, 0xd1, + 0x20, 0x00, 0x00, 0xf0, 0x6b, 0xf8, 0x2a, 0x00, 0x01, 0x00, 0x20, 0x00, + 0x00, 0xf0, 0x54, 0xf8, 0xed, 0xe7, 0x00, 0x20, 0x01, 0x2a, 0xea, 0xd0, + 0x51, 0x1c, 0x03, 0xd1, 0x16, 0x23, 0x01, 0x30, 0x23, 0x60, 0xe4, 0xe7, + 0x00, 0x24, 0x28, 0x00, 0x1c, 0x60, 0x90, 0x47, 0x20, 0x00, 0xde, 0xe7, + 0x70, 0xb5, 0x04, 0x00, 0x0d, 0x00, 0x1f, 0x29, 0x02, 0xd9, 0x01, 0x20, + 0x40, 0x42, 0x70, 0xbd, 0x43, 0x6c, 0x00, 0x2b, 0x12, 0xd0, 0x62, 0x6c, + 0xab, 0x00, 0xd2, 0x18, 0x13, 0x68, 0x01, 0x20, 0x00, 0x2b, 0xf4, 0xd0, + 0x02, 0x20, 0x59, 0x1c, 0xf1, 0xd0, 0x01, 0x30, 0x01, 0x2b, 0xee, 0xd0, + 0x00, 0x24, 0x28, 0x00, 0x14, 0x60, 0x98, 0x47, 0x20, 0x00, 0xe8, 0xe7, + 0xff, 0xf7, 0x88, 0xff, 0x00, 0x28, 0xe8, 0xd0, 0xe1, 0xe7, 0x10, 0xb5, + 0x04, 0x00, 0xf9, 0xf7, 0x21, 0xfb, 0x21, 0x00, 0xff, 0xf7, 0xac, 0xff, + 0x10, 0xbd, 0x70, 0xb5, 0x0d, 0x00, 0x04, 0x00, 0xf9, 0xf7, 0x18, 0xfb, + 0x2a, 0x00, 0x21, 0x00, 0xff, 0xf7, 0x89, 0xff, 0x70, 0xbd, 0x10, 0xb5, + 0xf9, 0xf7, 0x10, 0xfb, 0xff, 0xf7, 0x6e, 0xff, 0x10, 0xbd, 0x10, 0xb5, + 0x04, 0x00, 0xf9, 0xf7, 0x09, 0xfb, 0x21, 0x00, 0xff, 0xf7, 0xbe, 0xff, + 0x10, 0xbd, 0x00, 0x00, 0x00, 0x23, 0x70, 0xb5, 0x06, 0x4d, 0x04, 0x00, + 0x08, 0x00, 0x11, 0x00, 0x2b, 0x60, 0x04, 0xf0, 0x31, 0xfc, 0x43, 0x1c, + 0x03, 0xd1, 0x2b, 0x68, 0x00, 0x2b, 0x00, 0xd0, 0x23, 0x60, 0x70, 0xbd, + 0x20, 0x0e, 0x00, 0x20, 0x10, 0xb5, 0x04, 0xf0, 0x15, 0xfc, 0x10, 0xbd, + 0x0c, 0xb4, 0x00, 0xb5, 0x9f, 0xb0, 0x02, 0x91, 0x06, 0x91, 0x09, 0x49, + 0x20, 0xab, 0x07, 0x91, 0x04, 0x91, 0x08, 0x49, 0x04, 0xcb, 0x05, 0x91, + 0x02, 0xa9, 0x01, 0x93, 0x03, 0xf0, 0xce, 0xfc, 0x00, 0x23, 0x02, 0x9a, + 0x13, 0x70, 0x1f, 0xb0, 0x08, 0xbc, 0x02, 0xb0, 0x18, 0x47, 0xc0, 0x46, + 0xff, 0xff, 0xff, 0x7f, 0x08, 0x02, 0xff, 0xff, 0x0e, 0xb4, 0x10, 0xb5, + 0x0c, 0x4a, 0x9f, 0xb0, 0x21, 0xab, 0x10, 0xcb, 0x07, 0x92, 0x04, 0x92, + 0x0a, 0x4a, 0x01, 0x93, 0x05, 0x92, 0x02, 0x90, 0x06, 0x90, 0xf9, 0xf7, + 0xc3, 0xfa, 0x22, 0x00, 0x01, 0x9b, 0x02, 0xa9, 0x03, 0xf0, 0xae, 0xfc, + 0x00, 0x23, 0x02, 0x9a, 0x13, 0x70, 0x1f, 0xb0, 0x10, 0xbc, 0x08, 0xbc, + 0x03, 0xb0, 0x18, 0x47, 0xff, 0xff, 0xff, 0x7f, 0x08, 0x02, 0xff, 0xff, + 0x70, 0xb5, 0x0c, 0x00, 0x0e, 0x25, 0x49, 0x5f, 0x03, 0xf0, 0x8e, 0xff, + 0x00, 0x28, 0x03, 0xdb, 0x63, 0x6d, 0x1b, 0x18, 0x63, 0x65, 0x70, 0xbd, + 0xa3, 0x89, 0x02, 0x4a, 0x13, 0x40, 0xa3, 0x81, 0xf9, 0xe7, 0xc0, 0x46, + 0xff, 0xef, 0xff, 0xff, 0x00, 0x20, 0x70, 0x47, 0xf8, 0xb5, 0x1f, 0x00, + 0x8b, 0x89, 0x05, 0x00, 0x0c, 0x00, 0x16, 0x00, 0xdb, 0x05, 0x05, 0xd5, + 0x0e, 0x23, 0xc9, 0x5e, 0x00, 0x22, 0x02, 0x23, 0x02, 0xf0, 0x8a, 0xfe, + 0xa3, 0x89, 0x05, 0x4a, 0x28, 0x00, 0x13, 0x40, 0xa3, 0x81, 0x32, 0x00, + 0x0e, 0x23, 0xe1, 0x5e, 0x3b, 0x00, 0x01, 0xf0, 0x2d, 0xf8, 0xf8, 0xbd, + 0xff, 0xef, 0xff, 0xff, 0x70, 0xb5, 0x0c, 0x00, 0x0e, 0x25, 0x49, 0x5f, + 0x02, 0xf0, 0x76, 0xfe, 0xa3, 0x89, 0x42, 0x1c, 0x03, 0xd1, 0x05, 0x4a, + 0x13, 0x40, 0xa3, 0x81, 0x70, 0xbd, 0x80, 0x22, 0x52, 0x01, 0x13, 0x43, + 0xa3, 0x81, 0x60, 0x65, 0xf8, 0xe7, 0xc0, 0x46, 0xff, 0xef, 0xff, 0xff, + 0x10, 0xb5, 0x0e, 0x23, 0xc9, 0x5e, 0x01, 0xf0, 0x23, 0xf8, 0x10, 0xbd, + 0x00, 0x23, 0xc2, 0x5c, 0x01, 0x33, 0x00, 0x2a, 0xfb, 0xd1, 0x58, 0x1e, + 0x70, 0x47, 0x00, 0x00, 0x70, 0xb5, 0x16, 0x00, 0x0d, 0x00, 0x03, 0xf0, + 0x05, 0xfa, 0x00, 0x2e, 0x0d, 0xd0, 0x6b, 0x23, 0x6a, 0x00, 0x52, 0x0d, + 0x9b, 0x1a, 0x00, 0x2b, 0x07, 0xdd, 0x00, 0x24, 0x03, 0x4a, 0x1b, 0x05, + 0x9d, 0x18, 0x2b, 0x00, 0x22, 0x00, 0xfb, 0xf7, 0xfa, 0xfb, 0x70, 0xbd, + 0x00, 0x00, 0xf0, 0x3f, 0xf0, 0xb5, 0x1d, 0x00, 0x00, 0x23, 0xa5, 0xb0, + 0x20, 0x93, 0xac, 0x4b, 0x05, 0x90, 0x1b, 0x68, 0x08, 0x91, 0x18, 0x00, + 0x07, 0x93, 0x1b, 0x92, 0xff, 0xf7, 0xd2, 0xff, 0x00, 0x26, 0x04, 0x00, + 0x00, 0x27, 0x08, 0x9b, 0x1f, 0x93, 0x1f, 0x9a, 0x13, 0x78, 0x2b, 0x2b, + 0x58, 0xd0, 0x44, 0xd8, 0x0d, 0x2b, 0x3d, 0xd8, 0x08, 0x2b, 0x3d, 0xd8, + 0x00, 0x2b, 0x47, 0xd0, 0x00, 0x23, 0x0e, 0x93, 0x00, 0x22, 0x1f, 0x9b, + 0x0a, 0x92, 0x06, 0x93, 0x1b, 0x78, 0x30, 0x2b, 0x00, 0xd0, 0x7f, 0xe0, + 0x06, 0x9b, 0x20, 0x32, 0x5b, 0x78, 0x93, 0x43, 0x58, 0x2b, 0x00, 0xd0, + 0x6e, 0xe0, 0x0e, 0x9b, 0x02, 0x95, 0x01, 0x93, 0x20, 0xab, 0x00, 0x93, + 0x95, 0x4a, 0x21, 0xab, 0x05, 0x98, 0x1f, 0xa9, 0x02, 0xf0, 0xbf, 0xfa, + 0x07, 0x23, 0x05, 0x00, 0x04, 0x00, 0x1d, 0x40, 0x18, 0x42, 0x06, 0xd0, + 0x06, 0x2d, 0x2f, 0xd1, 0x06, 0x9b, 0x01, 0x33, 0x1f, 0x93, 0x00, 0x23, + 0x0e, 0x93, 0x1b, 0x9b, 0x00, 0x2b, 0x02, 0xd0, 0x1b, 0x9b, 0x1f, 0x9a, + 0x1a, 0x60, 0x0e, 0x9b, 0x00, 0x2b, 0x1c, 0xd0, 0x80, 0x23, 0x32, 0x00, + 0x1b, 0x06, 0xfb, 0x18, 0x10, 0x00, 0x19, 0x00, 0x25, 0xb0, 0xf0, 0xbd, + 0x20, 0x2b, 0xc3, 0xd1, 0x01, 0x32, 0x1f, 0x92, 0xb5, 0xe7, 0x2d, 0x2b, + 0xbe, 0xd1, 0x2c, 0x3b, 0x0e, 0x93, 0x53, 0x1c, 0x1f, 0x93, 0x53, 0x78, + 0x00, 0x2b, 0xb9, 0xd1, 0x08, 0x9b, 0x1f, 0x93, 0x00, 0x23, 0x0e, 0x93, + 0x1b, 0x9b, 0x00, 0x2b, 0xdc, 0xd1, 0x32, 0x00, 0x3b, 0x00, 0xe3, 0xe7, + 0x00, 0x23, 0xed, 0xe7, 0x20, 0x9a, 0x00, 0x2a, 0x07, 0xd0, 0x35, 0x21, + 0x22, 0xa8, 0x03, 0xf0, 0x95, 0xfa, 0x20, 0x99, 0x05, 0x98, 0x02, 0xf0, + 0x37, 0xfe, 0x68, 0x1e, 0x04, 0x28, 0x06, 0xd8, 0x04, 0xf0, 0xde, 0xfb, + 0x0b, 0x03, 0x16, 0x18, 0x0b, 0x00, 0x22, 0x9e, 0x23, 0x9f, 0x23, 0x07, + 0xbd, 0xd5, 0x80, 0x23, 0x1b, 0x06, 0x1f, 0x43, 0xb9, 0xe7, 0x23, 0x9b, + 0x69, 0x4a, 0x6a, 0x49, 0x1a, 0x40, 0x21, 0x9b, 0x22, 0x9e, 0x5b, 0x18, + 0x1b, 0x05, 0x1a, 0x43, 0x17, 0x00, 0xee, 0xe7, 0x66, 0x4f, 0xec, 0xe7, + 0x01, 0x26, 0x66, 0x4f, 0x76, 0x42, 0xe8, 0xe7, 0x1f, 0x9b, 0x5a, 0x1c, + 0x1f, 0x92, 0x5b, 0x78, 0x30, 0x2b, 0xf9, 0xd0, 0x00, 0x2b, 0xa0, 0xd0, + 0x01, 0x23, 0x0a, 0x93, 0x1f, 0x9b, 0x0a, 0x22, 0x10, 0x93, 0x00, 0x23, + 0x0f, 0x93, 0x0b, 0x93, 0x09, 0x93, 0x1f, 0x98, 0x05, 0x78, 0x2b, 0x00, + 0x30, 0x3b, 0xd9, 0xb2, 0x09, 0x29, 0x27, 0xd9, 0x22, 0x00, 0x07, 0x99, + 0x04, 0xf0, 0x32, 0xf8, 0x00, 0x28, 0x33, 0xd0, 0x00, 0x20, 0x2b, 0x00, + 0x84, 0x46, 0x09, 0x9a, 0x0c, 0x90, 0x06, 0x92, 0x20, 0x22, 0x19, 0x00, + 0x91, 0x43, 0x0a, 0x00, 0x00, 0x21, 0x07, 0x91, 0x45, 0x2a, 0x00, 0xd0, + 0xc5, 0xe0, 0x06, 0x9b, 0x0a, 0x9a, 0x03, 0x43, 0x13, 0x43, 0x8b, 0x42, + 0x94, 0xd0, 0x1f, 0x9b, 0x08, 0x93, 0x01, 0x33, 0x1f, 0x93, 0x08, 0x9b, + 0x5b, 0x78, 0x2b, 0x2b, 0x76, 0xd0, 0x0c, 0x00, 0x2d, 0x2b, 0x79, 0xd1, + 0x01, 0x24, 0x72, 0xe0, 0x09, 0x99, 0x08, 0x29, 0x09, 0xdc, 0x0b, 0x99, + 0x51, 0x43, 0x5b, 0x18, 0x0b, 0x93, 0x09, 0x9b, 0x01, 0x30, 0x01, 0x33, + 0x09, 0x93, 0x1f, 0x90, 0xc3, 0xe7, 0x0f, 0x99, 0x51, 0x43, 0x5b, 0x18, + 0x0f, 0x93, 0xf4, 0xe7, 0x1f, 0x9b, 0x09, 0x9a, 0x1c, 0x19, 0x1f, 0x94, + 0x23, 0x78, 0x00, 0x2a, 0x39, 0xd0, 0x0c, 0x90, 0x06, 0x92, 0x1a, 0x00, + 0x30, 0x3a, 0x09, 0x2a, 0x12, 0xd9, 0x01, 0x22, 0x94, 0x46, 0xc1, 0xe7, + 0x1f, 0x9b, 0x01, 0x30, 0x5a, 0x1c, 0x1f, 0x92, 0x5b, 0x78, 0x30, 0x2b, + 0xf8, 0xd0, 0x1a, 0x00, 0x31, 0x3a, 0x08, 0x2a, 0x3f, 0xd8, 0x0c, 0x90, + 0x00, 0x20, 0x1f, 0x9a, 0x06, 0x90, 0x10, 0x92, 0x1a, 0x00, 0x41, 0x1c, + 0x30, 0x3a, 0x30, 0x2b, 0x15, 0xd0, 0x0c, 0x9b, 0x5b, 0x18, 0x0a, 0x21, + 0x0c, 0x93, 0x06, 0x9b, 0xc4, 0x18, 0xa3, 0x42, 0x15, 0xd1, 0x06, 0x99, + 0x06, 0x9b, 0x01, 0x31, 0x09, 0x18, 0x1b, 0x18, 0x06, 0x91, 0x08, 0x2b, + 0x1b, 0xdc, 0x0a, 0x23, 0x0b, 0x99, 0x4b, 0x43, 0x00, 0x21, 0xd3, 0x18, + 0x0b, 0x93, 0x1f, 0x9b, 0x08, 0x00, 0x5a, 0x1c, 0x1f, 0x92, 0x5b, 0x78, + 0xc7, 0xe7, 0x09, 0x98, 0xd1, 0xe7, 0x08, 0x2b, 0x04, 0xdc, 0x0b, 0x9d, + 0x4d, 0x43, 0x0b, 0x95, 0x01, 0x33, 0xe0, 0xe7, 0x5d, 0x1c, 0x10, 0x2d, + 0xfa, 0xdc, 0x0f, 0x9d, 0x4d, 0x43, 0x0f, 0x95, 0xf6, 0xe7, 0x06, 0x9b, + 0x00, 0x21, 0x10, 0x2b, 0xe5, 0xdc, 0x0a, 0x23, 0x0f, 0x98, 0x43, 0x43, + 0xd3, 0x18, 0x0f, 0x93, 0xdf, 0xe7, 0x00, 0x22, 0x0c, 0x92, 0x06, 0x92, + 0x01, 0x32, 0xad, 0xe7, 0x00, 0x24, 0x08, 0x9b, 0x02, 0x33, 0x1f, 0x93, + 0x08, 0x9b, 0x9b, 0x78, 0x1a, 0x00, 0x30, 0x3a, 0x09, 0x2a, 0x13, 0xd9, + 0x08, 0x9a, 0x1f, 0x92, 0x00, 0x22, 0x31, 0xe0, 0xc8, 0x03, 0x01, 0x10, + 0xd8, 0x01, 0x01, 0x10, 0xff, 0xff, 0xef, 0xff, 0x33, 0x04, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x9b, 0x5a, 0x1c, + 0x1f, 0x92, 0x5b, 0x78, 0x30, 0x2b, 0xf9, 0xd0, 0x00, 0x22, 0x07, 0x92, + 0x1a, 0x00, 0x31, 0x3a, 0x08, 0x2a, 0x1a, 0xd8, 0x30, 0x3b, 0x1a, 0x00, + 0x1f, 0x9b, 0x07, 0x93, 0x1f, 0x9b, 0x59, 0x1c, 0x1f, 0x91, 0x5b, 0x78, + 0x1d, 0x00, 0x30, 0x3d, 0x09, 0x2d, 0x3a, 0xd9, 0x07, 0x9d, 0x49, 0x1b, + 0xb1, 0x4d, 0x07, 0x95, 0x08, 0x29, 0x03, 0xdc, 0x07, 0x92, 0xaa, 0x42, + 0x00, 0xdd, 0x07, 0x95, 0x00, 0x2c, 0x02, 0xd0, 0x07, 0x9a, 0x52, 0x42, + 0x07, 0x92, 0x06, 0x9a, 0x00, 0x2a, 0x4c, 0xd1, 0x0a, 0x9a, 0x10, 0x43, + 0x00, 0xd0, 0xae, 0xe6, 0x62, 0x46, 0x00, 0x2a, 0x00, 0xd0, 0xc9, 0xe6, + 0x69, 0x2b, 0x26, 0xd0, 0x22, 0xdc, 0x49, 0x2b, 0x23, 0xd0, 0x4e, 0x2b, + 0x00, 0xd0, 0xc1, 0xe6, 0xa2, 0x49, 0x1f, 0xa8, 0x02, 0xf0, 0xa0, 0xfb, + 0x00, 0x28, 0x00, 0xd1, 0xba, 0xe6, 0x1f, 0x9b, 0x1b, 0x78, 0x28, 0x2b, + 0x2b, 0xd1, 0x9e, 0x49, 0x22, 0xaa, 0x14, 0x31, 0x1f, 0xa8, 0x02, 0xf0, + 0xa7, 0xfb, 0x05, 0x28, 0x23, 0xd1, 0x23, 0x9b, 0x9a, 0x4a, 0x22, 0x9e, + 0x1a, 0x43, 0x17, 0x00, 0x89, 0xe6, 0x0a, 0x21, 0x4a, 0x43, 0xd2, 0x18, + 0x30, 0x3a, 0xb7, 0xe7, 0x6e, 0x2b, 0xdf, 0xd0, 0xa0, 0xe6, 0x95, 0x49, + 0x1f, 0xa8, 0x02, 0xf0, 0x7f, 0xfb, 0x00, 0x28, 0x00, 0xd1, 0x99, 0xe6, + 0x1f, 0x9b, 0x92, 0x49, 0x01, 0x3b, 0x1f, 0xa8, 0x1f, 0x93, 0x02, 0xf0, + 0x75, 0xfb, 0x00, 0x28, 0x02, 0xd1, 0x1f, 0x9b, 0x01, 0x33, 0x1f, 0x93, + 0x00, 0x26, 0x8a, 0x4f, 0x6b, 0xe6, 0x8c, 0x48, 0x03, 0xf0, 0xfe, 0xfe, + 0x06, 0x00, 0x0f, 0x00, 0x65, 0xe6, 0x07, 0x9b, 0x0c, 0x9a, 0x9b, 0x1a, + 0x0a, 0x93, 0x09, 0x9b, 0x00, 0x2b, 0x01, 0xd1, 0x06, 0x9b, 0x09, 0x93, + 0x06, 0x9c, 0x10, 0x2c, 0x00, 0xdd, 0x10, 0x24, 0x0b, 0x98, 0xfb, 0xf7, + 0x7b, 0xfa, 0x06, 0x9b, 0x06, 0x00, 0x0f, 0x00, 0x09, 0x2b, 0x15, 0xdd, + 0x22, 0x00, 0x7f, 0x4b, 0x09, 0x3a, 0xd2, 0x00, 0x9b, 0x18, 0x1a, 0x68, + 0x5b, 0x68, 0xfb, 0xf7, 0xf8, 0xf9, 0x06, 0x00, 0x0f, 0x98, 0x0f, 0x00, + 0xfb, 0xf7, 0x68, 0xfa, 0x02, 0x00, 0x0b, 0x00, 0x30, 0x00, 0x39, 0x00, + 0xfb, 0xf7, 0xc6, 0xf9, 0x06, 0x00, 0x0f, 0x00, 0x06, 0x9b, 0x0f, 0x2b, + 0x39, 0xdc, 0x0a, 0x9b, 0x00, 0x2b, 0x00, 0xd1, 0x33, 0xe6, 0x24, 0xdd, + 0x16, 0x2b, 0x09, 0xdc, 0x6f, 0x49, 0xdb, 0x00, 0xc9, 0x18, 0x32, 0x00, + 0x08, 0x68, 0x49, 0x68, 0x3b, 0x00, 0xfb, 0xf7, 0xd8, 0xf9, 0xbd, 0xe7, + 0x25, 0x23, 0x06, 0x9a, 0x9b, 0x1a, 0x0a, 0x9a, 0x93, 0x42, 0x22, 0xdb, + 0x0f, 0x24, 0x06, 0x9b, 0x66, 0x4d, 0xe4, 0x1a, 0xe1, 0x00, 0x69, 0x18, + 0x32, 0x00, 0x08, 0x68, 0x49, 0x68, 0x3b, 0x00, 0xfb, 0xf7, 0xc5, 0xf9, + 0x0a, 0x9b, 0x1c, 0x1b, 0xe4, 0x00, 0x2c, 0x19, 0x22, 0x68, 0x63, 0x68, + 0xe3, 0xe7, 0x0a, 0x9b, 0x16, 0x33, 0x0c, 0xdb, 0x0c, 0x9b, 0x07, 0x9a, + 0x30, 0x00, 0x9a, 0x1a, 0x5a, 0x4b, 0xd2, 0x00, 0x9b, 0x18, 0x39, 0x00, + 0x1a, 0x68, 0x5b, 0x68, 0xfb, 0xf7, 0x91, 0xf9, 0x94, 0xe7, 0x06, 0x9b, + 0x1c, 0x1b, 0x0a, 0x9b, 0xe4, 0x18, 0x00, 0x2c, 0x72, 0xdd, 0x0f, 0x23, + 0x21, 0x00, 0x19, 0x40, 0x1c, 0x42, 0x0a, 0xd0, 0xcb, 0x00, 0x50, 0x49, + 0x32, 0x00, 0xc9, 0x18, 0x08, 0x68, 0x49, 0x68, 0x3b, 0x00, 0xfb, 0xf7, + 0x9a, 0xf9, 0x06, 0x00, 0x0f, 0x00, 0x0f, 0x23, 0x9c, 0x43, 0x4a, 0xd0, + 0x26, 0x33, 0xff, 0x33, 0x9c, 0x42, 0x22, 0xdd, 0x00, 0x23, 0x06, 0x93, + 0x07, 0x93, 0x0b, 0x93, 0x09, 0x93, 0x22, 0x23, 0x00, 0x26, 0x05, 0x9a, + 0x3f, 0x4f, 0x13, 0x60, 0x0b, 0x9b, 0xb3, 0x42, 0x00, 0xd1, 0xd2, 0xe5, + 0x20, 0x99, 0x05, 0x98, 0x02, 0xf0, 0x3c, 0xfc, 0x09, 0x99, 0x05, 0x98, + 0x02, 0xf0, 0x38, 0xfc, 0x07, 0x99, 0x05, 0x98, 0x02, 0xf0, 0x34, 0xfc, + 0x0b, 0x99, 0x05, 0x98, 0x02, 0xf0, 0x30, 0xfc, 0x06, 0x99, 0x05, 0x98, + 0x02, 0xf0, 0x2c, 0xfc, 0xbd, 0xe5, 0x00, 0x23, 0x30, 0x00, 0x39, 0x00, + 0x35, 0x4d, 0x24, 0x11, 0x08, 0x93, 0x01, 0x2c, 0x1e, 0xdc, 0x00, 0x2b, + 0x01, 0xd0, 0x06, 0x00, 0x0f, 0x00, 0x32, 0x4b, 0x32, 0x00, 0xff, 0x18, + 0x08, 0x9b, 0xdd, 0x00, 0x2e, 0x4b, 0x5d, 0x19, 0x28, 0x68, 0x69, 0x68, + 0x3b, 0x00, 0xfb, 0xf7, 0x56, 0xf9, 0x26, 0x4b, 0x2c, 0x4a, 0x06, 0x00, + 0x0b, 0x40, 0x93, 0x42, 0xbe, 0xd8, 0x2b, 0x4a, 0x93, 0x42, 0x13, 0xd9, + 0x01, 0x26, 0x2a, 0x4f, 0x76, 0x42, 0x00, 0x23, 0x08, 0x93, 0x89, 0xe0, + 0x01, 0x22, 0x14, 0x42, 0x04, 0xd0, 0x2a, 0x68, 0x6b, 0x68, 0xfb, 0xf7, + 0x40, 0xf9, 0x01, 0x23, 0x08, 0x9a, 0x64, 0x10, 0x01, 0x32, 0x08, 0x92, + 0x08, 0x35, 0xd0, 0xe7, 0xd4, 0x23, 0x9b, 0x04, 0xcf, 0x18, 0xea, 0xe7, + 0x00, 0x2c, 0xe8, 0xd0, 0x64, 0x42, 0x0f, 0x22, 0x23, 0x00, 0x13, 0x40, + 0x14, 0x42, 0x0a, 0xd0, 0xda, 0x00, 0x15, 0x4b, 0x30, 0x00, 0x9b, 0x18, + 0x39, 0x00, 0x1a, 0x68, 0x5b, 0x68, 0xfb, 0xf7, 0x06, 0xf9, 0x06, 0x00, + 0x0f, 0x00, 0x24, 0x11, 0xd5, 0xd0, 0x1f, 0x2c, 0x28, 0xdd, 0x00, 0x23, + 0x06, 0x93, 0x07, 0x93, 0x0b, 0x93, 0x09, 0x93, 0x22, 0x23, 0x05, 0x9a, + 0x00, 0x26, 0x13, 0x60, 0x0b, 0x9b, 0x00, 0x27, 0x00, 0x2b, 0x8d, 0xd1, + 0x5f, 0xe5, 0xc0, 0x46, 0x1f, 0x4e, 0x00, 0x00, 0xa9, 0x01, 0x01, 0x10, + 0xd8, 0x01, 0x01, 0x10, 0x00, 0x00, 0xf0, 0x7f, 0xa1, 0x01, 0x01, 0x10, + 0x2c, 0x03, 0x01, 0x10, 0x11, 0xfd, 0x00, 0x10, 0x70, 0x04, 0x01, 0x10, + 0x48, 0x04, 0x01, 0x10, 0x00, 0x00, 0xb0, 0xfc, 0x00, 0x00, 0xa0, 0x7c, + 0x00, 0x00, 0x90, 0x7c, 0xff, 0xff, 0xef, 0x7f, 0x10, 0x23, 0x22, 0x00, + 0x1a, 0x40, 0x08, 0x92, 0x1c, 0x42, 0x01, 0xd0, 0x5a, 0x33, 0x08, 0x93, + 0x30, 0x00, 0x39, 0x00, 0x00, 0x23, 0xc6, 0x4d, 0x28, 0x35, 0x01, 0x22, + 0x14, 0x42, 0x04, 0xd0, 0x2a, 0x68, 0x6b, 0x68, 0xfb, 0xf7, 0xe1, 0xf8, + 0x01, 0x23, 0x64, 0x10, 0x08, 0x35, 0x00, 0x2c, 0xf3, 0xd1, 0x00, 0x2b, + 0x01, 0xd0, 0x06, 0x00, 0x0f, 0x00, 0x08, 0x9b, 0x00, 0x2b, 0x0f, 0xd0, + 0x6b, 0x23, 0x7a, 0x00, 0x52, 0x0d, 0x39, 0x00, 0x9b, 0x1a, 0x00, 0x2b, + 0x08, 0xdd, 0x1f, 0x2b, 0x00, 0xdc, 0x24, 0xe1, 0x00, 0x26, 0x34, 0x2b, + 0x00, 0xdc, 0x19, 0xe1, 0xdc, 0x27, 0xbf, 0x04, 0x00, 0x22, 0x00, 0x23, + 0x30, 0x00, 0x39, 0x00, 0xfb, 0xf7, 0x02, 0xf9, 0x00, 0x28, 0x9e, 0xd1, + 0x0b, 0x9b, 0x09, 0x9a, 0x00, 0x93, 0x10, 0x99, 0x06, 0x9b, 0x05, 0x98, + 0x02, 0xf0, 0xda, 0xfb, 0x0b, 0x90, 0x00, 0x28, 0x00, 0xd1, 0x1f, 0xe7, + 0x0a, 0x9b, 0x07, 0x99, 0xda, 0x17, 0x0c, 0x9b, 0x5b, 0x1a, 0x1a, 0x40, + 0x0a, 0x9b, 0x15, 0x92, 0xdb, 0x43, 0x0a, 0x9a, 0xdb, 0x17, 0x1a, 0x40, + 0x00, 0x23, 0x1a, 0x92, 0x06, 0x93, 0x07, 0x93, 0x0b, 0x9b, 0x05, 0x98, + 0x59, 0x68, 0x02, 0xf0, 0x15, 0xfb, 0x09, 0x90, 0x00, 0x28, 0x00, 0xd1, + 0x0b, 0xe7, 0x0b, 0x9b, 0x0b, 0x99, 0x1b, 0x69, 0x0c, 0x31, 0x9a, 0x1c, + 0x92, 0x00, 0x0c, 0x30, 0x0c, 0x93, 0xfb, 0xf7, 0x19, 0xfd, 0x22, 0xab, + 0x01, 0x93, 0x21, 0xab, 0x00, 0x93, 0x32, 0x00, 0x3b, 0x00, 0x05, 0x98, + 0x12, 0x96, 0x13, 0x97, 0x02, 0xf0, 0xf2, 0xfe, 0x20, 0x90, 0x00, 0x28, + 0x00, 0xd1, 0xf2, 0xe6, 0x01, 0x21, 0x05, 0x98, 0x02, 0xf0, 0x34, 0xfc, + 0x07, 0x90, 0x00, 0x28, 0x00, 0xd1, 0xea, 0xe6, 0x21, 0x9b, 0x1a, 0x9a, + 0x15, 0x9d, 0xd4, 0x1a, 0x00, 0x2b, 0x01, 0xdb, 0x1a, 0x9c, 0x5d, 0x19, + 0x08, 0x99, 0x22, 0x9a, 0x5b, 0x1a, 0x36, 0x21, 0x9b, 0x18, 0x8a, 0x1a, + 0x86, 0x49, 0x01, 0x20, 0x8c, 0x46, 0x00, 0x21, 0x01, 0x3b, 0x10, 0x91, + 0x14, 0x90, 0x63, 0x45, 0x07, 0xda, 0x61, 0x46, 0xc9, 0x1a, 0x52, 0x1a, + 0x1f, 0x29, 0x00, 0xdd, 0xb8, 0xe0, 0x88, 0x40, 0x14, 0x90, 0xab, 0x18, + 0x0c, 0x93, 0xa4, 0x18, 0x08, 0x9b, 0x0c, 0x9a, 0x1c, 0x19, 0x2b, 0x00, + 0x95, 0x42, 0x00, 0xdd, 0x13, 0x00, 0xa3, 0x42, 0x00, 0xdd, 0x23, 0x00, + 0x00, 0x2b, 0x04, 0xdd, 0x0c, 0x9a, 0xe4, 0x1a, 0xd2, 0x1a, 0x0c, 0x92, + 0xed, 0x1a, 0x15, 0x9b, 0x00, 0x2b, 0x17, 0xdd, 0x1a, 0x00, 0x07, 0x99, + 0x05, 0x98, 0x02, 0xf0, 0xbb, 0xfc, 0x07, 0x90, 0x00, 0x28, 0x00, 0xd1, + 0xab, 0xe6, 0x01, 0x00, 0x20, 0x9a, 0x05, 0x98, 0x02, 0xf0, 0x02, 0xfc, + 0x0f, 0x90, 0x00, 0x28, 0x00, 0xd1, 0xa2, 0xe6, 0x20, 0x99, 0x05, 0x98, + 0x02, 0xf0, 0xe8, 0xfa, 0x0f, 0x9b, 0x20, 0x93, 0x0c, 0x9b, 0x00, 0x2b, + 0x00, 0xdd, 0x89, 0xe0, 0x0a, 0x9b, 0x00, 0x2b, 0x08, 0xdd, 0x1a, 0x9a, + 0x09, 0x99, 0x05, 0x98, 0x02, 0xf0, 0x9c, 0xfc, 0x09, 0x90, 0x00, 0x28, + 0x00, 0xd1, 0x8c, 0xe6, 0x00, 0x2c, 0x08, 0xdd, 0x22, 0x00, 0x09, 0x99, + 0x05, 0x98, 0x02, 0xf0, 0xed, 0xfc, 0x09, 0x90, 0x00, 0x28, 0x00, 0xd1, + 0x81, 0xe6, 0x00, 0x2d, 0x08, 0xdd, 0x2a, 0x00, 0x07, 0x99, 0x05, 0x98, + 0x02, 0xf0, 0xe2, 0xfc, 0x07, 0x90, 0x00, 0x28, 0x00, 0xd1, 0x76, 0xe6, + 0x09, 0x9a, 0x20, 0x99, 0x05, 0x98, 0x02, 0xf0, 0x62, 0xfd, 0x06, 0x90, + 0x00, 0x28, 0x00, 0xd1, 0x6d, 0xe6, 0x00, 0x22, 0xc3, 0x68, 0x07, 0x99, + 0xc2, 0x60, 0x0f, 0x93, 0x02, 0xf0, 0x3c, 0xfd, 0x00, 0x28, 0x5f, 0xda, + 0x0f, 0x9b, 0x33, 0x43, 0x00, 0xd0, 0x8a, 0xe0, 0x3b, 0x03, 0x00, 0xd0, + 0x87, 0xe0, 0xd6, 0x22, 0x47, 0x4b, 0xd2, 0x04, 0x3b, 0x40, 0x93, 0x42, + 0x00, 0xd8, 0x80, 0xe0, 0x06, 0x9b, 0x5b, 0x69, 0x0a, 0x93, 0x00, 0x2b, + 0x04, 0xd1, 0x06, 0x9b, 0x1b, 0x69, 0x0a, 0x93, 0x01, 0x2b, 0x76, 0xdd, + 0x06, 0x99, 0x01, 0x22, 0x05, 0x98, 0x02, 0xf0, 0xaf, 0xfc, 0x07, 0x99, + 0x06, 0x90, 0x02, 0xf0, 0x19, 0xfd, 0x00, 0x28, 0x6b, 0xdd, 0x08, 0x99, + 0x3b, 0x00, 0x39, 0x4a, 0x00, 0x29, 0x00, 0xd1, 0x93, 0xe0, 0x11, 0x00, + 0xd6, 0x20, 0x39, 0x40, 0xc0, 0x04, 0x81, 0x42, 0x00, 0xdd, 0x8c, 0xe0, + 0xdc, 0x23, 0x9b, 0x04, 0x99, 0x42, 0x00, 0xdc, 0xa2, 0xe6, 0x30, 0x00, + 0x39, 0x00, 0x00, 0x22, 0x30, 0x4b, 0xfa, 0xf7, 0xb6, 0xff, 0x06, 0x00, + 0x0f, 0x00, 0x08, 0x43, 0x00, 0xd0, 0x2d, 0xe6, 0x22, 0x23, 0x05, 0x9a, + 0x13, 0x60, 0x29, 0xe6, 0x4b, 0x23, 0x9a, 0x1a, 0x4c, 0x3b, 0x93, 0x40, + 0x19, 0x40, 0x0f, 0x00, 0xe0, 0xe6, 0x01, 0x22, 0x52, 0x42, 0x9a, 0x40, + 0x16, 0x40, 0xdb, 0xe6, 0x25, 0x49, 0xcb, 0x1a, 0x01, 0x00, 0x99, 0x40, + 0x10, 0x91, 0x41, 0xe7, 0x0c, 0x9a, 0x20, 0x99, 0x05, 0x98, 0x02, 0xf0, + 0x71, 0xfc, 0x20, 0x90, 0x00, 0x28, 0x00, 0xd0, 0x6c, 0xe7, 0x04, 0xe6, + 0x0c, 0x97, 0x00, 0x28, 0x77, 0xd1, 0x0f, 0x9a, 0x3b, 0x03, 0x1b, 0x0b, + 0x00, 0x2a, 0x39, 0xd0, 0x1a, 0x4a, 0x93, 0x42, 0x39, 0xd1, 0x01, 0x22, + 0x08, 0x9b, 0x52, 0x42, 0x31, 0x00, 0x10, 0x00, 0x00, 0x2b, 0x0b, 0xd0, + 0xd4, 0x24, 0x12, 0x4b, 0x10, 0x00, 0x3b, 0x40, 0xe4, 0x04, 0xa3, 0x42, + 0x04, 0xd8, 0x6c, 0x30, 0x1b, 0x0d, 0xc3, 0x1a, 0x9a, 0x40, 0x10, 0x00, + 0x81, 0x42, 0x24, 0xd1, 0x0f, 0x4b, 0x0c, 0x9a, 0x9a, 0x42, 0x02, 0xd1, + 0x4b, 0x1c, 0x00, 0xd1, 0xdd, 0xe5, 0x08, 0x4b, 0x0c, 0x9a, 0x00, 0x26, + 0x1a, 0x40, 0x13, 0x00, 0x80, 0x22, 0x52, 0x03, 0x9f, 0x18, 0x08, 0x9b, + 0x00, 0x2b, 0xa2, 0xd1, 0xda, 0xe5, 0xc0, 0x46, 0xd8, 0x01, 0x01, 0x10, + 0x02, 0xfc, 0xff, 0xff, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x50, 0x39, + 0xe2, 0xfb, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0xff, 0xff, 0xef, 0x7f, + 0x33, 0x43, 0x00, 0xd1, 0x7d, 0xe7, 0x10, 0x9b, 0x00, 0x2b, 0x1d, 0xd0, + 0x0c, 0x9b, 0x10, 0x9a, 0x13, 0x42, 0xe2, 0xd0, 0x0f, 0x9b, 0x30, 0x00, + 0x39, 0x00, 0x08, 0x9a, 0x00, 0x2b, 0x17, 0xd0, 0xff, 0xf7, 0x2e, 0xfb, + 0x02, 0x00, 0x0b, 0x00, 0x12, 0x98, 0x13, 0x99, 0xfa, 0xf7, 0x10, 0xff, + 0x06, 0x00, 0x0f, 0x00, 0xd1, 0xe7, 0x01, 0x26, 0x13, 0x40, 0x99, 0x4a, + 0x76, 0x42, 0x9b, 0x18, 0x98, 0x4a, 0x1a, 0x43, 0x17, 0x00, 0xc8, 0xe7, + 0x14, 0x9b, 0x33, 0x42, 0xc5, 0xd0, 0xe1, 0xe7, 0xff, 0xf7, 0x16, 0xfb, + 0x02, 0x00, 0x0b, 0x00, 0x12, 0x98, 0x13, 0x99, 0xfa, 0xf7, 0xef, 0xfe, + 0x00, 0x22, 0x00, 0x23, 0x06, 0x00, 0x0f, 0x00, 0xfa, 0xf7, 0x5c, 0xff, + 0x00, 0x28, 0xb4, 0xd0, 0xfc, 0xe5, 0x07, 0x99, 0x06, 0x98, 0x02, 0xf0, + 0xe5, 0xfd, 0x80, 0x23, 0x00, 0x22, 0xdb, 0x05, 0x04, 0x00, 0x0d, 0x00, + 0xfa, 0xf7, 0x5c, 0xff, 0x00, 0x28, 0x75, 0xd0, 0x0f, 0x9b, 0x00, 0x2b, + 0x47, 0xd0, 0x00, 0x23, 0x84, 0x4c, 0x00, 0x25, 0x10, 0x93, 0x11, 0x94, + 0x82, 0x4c, 0x83, 0x4a, 0x0c, 0x9b, 0x13, 0x40, 0x14, 0x93, 0x14, 0x9a, + 0x81, 0x4b, 0x9a, 0x42, 0x00, 0xd0, 0xac, 0xe0, 0x80, 0x4a, 0x0c, 0x9b, + 0x94, 0x46, 0x63, 0x44, 0x1f, 0x00, 0x10, 0x9a, 0x11, 0x9b, 0x30, 0x00, + 0x39, 0x00, 0x0c, 0x92, 0x0d, 0x93, 0x02, 0xf0, 0xe5, 0xfc, 0x02, 0x00, + 0x0b, 0x00, 0x0c, 0x98, 0x0d, 0x99, 0xfa, 0xf7, 0xe4, 0xfe, 0x32, 0x00, + 0x3b, 0x00, 0xfa, 0xf7, 0xb9, 0xfe, 0x73, 0x4a, 0x75, 0x4b, 0x06, 0x00, + 0x0a, 0x40, 0x9a, 0x42, 0x5e, 0xd9, 0x13, 0x9a, 0x73, 0x4b, 0x9a, 0x42, + 0x03, 0xd1, 0x12, 0x9b, 0x01, 0x33, 0x00, 0xd1, 0x45, 0xe5, 0x01, 0x26, + 0x6f, 0x4f, 0x76, 0x42, 0x20, 0x99, 0x05, 0x98, 0x02, 0xf0, 0x88, 0xf9, + 0x09, 0x99, 0x05, 0x98, 0x02, 0xf0, 0x84, 0xf9, 0x07, 0x99, 0x05, 0x98, + 0x02, 0xf0, 0x80, 0xf9, 0x06, 0x99, 0x05, 0x98, 0x02, 0xf0, 0x7c, 0xf9, + 0x1c, 0xe6, 0x00, 0x2e, 0x1c, 0xd1, 0x0c, 0x9b, 0x1b, 0x03, 0x1f, 0xd1, + 0x00, 0x22, 0x20, 0x00, 0x29, 0x00, 0x5d, 0x4b, 0xfa, 0xf7, 0xfe, 0xfe, + 0x00, 0x28, 0x1a, 0xd1, 0x20, 0x00, 0x29, 0x00, 0x00, 0x22, 0x5f, 0x4b, + 0xfa, 0xf7, 0xab, 0xfe, 0x05, 0x00, 0x0c, 0x00, 0x80, 0x23, 0x1b, 0x06, + 0xe3, 0x18, 0x1c, 0x95, 0x1d, 0x93, 0x1c, 0x9a, 0x1d, 0x9b, 0x10, 0x92, + 0x11, 0x93, 0x9e, 0xe7, 0x01, 0x2e, 0x03, 0xd1, 0x0c, 0x9b, 0x00, 0x2b, + 0x00, 0xd1, 0x7f, 0xe5, 0x00, 0x23, 0x55, 0x4c, 0x91, 0xe7, 0x0f, 0x9d, + 0x52, 0x4c, 0xe9, 0xe7, 0x00, 0x22, 0x20, 0x00, 0x29, 0x00, 0x50, 0x4b, + 0xfa, 0xf7, 0x8d, 0xfe, 0x0f, 0x9a, 0x05, 0x00, 0x0b, 0x00, 0x0c, 0x00, + 0x00, 0x2a, 0x07, 0xd1, 0x80, 0x22, 0x12, 0x06, 0x8b, 0x18, 0x16, 0x90, + 0x17, 0x93, 0x16, 0x9a, 0x17, 0x9b, 0xdc, 0xe7, 0x02, 0x00, 0x16, 0x92, + 0x17, 0x93, 0xf8, 0xe7, 0xd4, 0x23, 0x9b, 0x04, 0xcf, 0x18, 0x08, 0x9b, + 0x00, 0x2b, 0xa5, 0xd1, 0x3d, 0x4b, 0x14, 0x9a, 0x3b, 0x40, 0x9a, 0x42, + 0xa0, 0xd1, 0x28, 0x00, 0x21, 0x00, 0xfa, 0xf7, 0x39, 0xff, 0xfa, 0xf7, + 0x2b, 0xff, 0x02, 0x00, 0x0b, 0x00, 0x28, 0x00, 0x21, 0x00, 0xfa, 0xf7, + 0x34, 0xfe, 0x3b, 0x03, 0x0f, 0x9a, 0x1b, 0x0b, 0x33, 0x43, 0x13, 0x43, + 0x04, 0x00, 0x0d, 0x00, 0x38, 0x4a, 0x00, 0x2b, 0x55, 0xd0, 0x38, 0x4b, + 0xfa, 0xf7, 0xa2, 0xfe, 0x00, 0x28, 0x00, 0xd0, 0xd0, 0xe4, 0x20, 0x00, + 0x29, 0x00, 0x35, 0x4a, 0x30, 0x4b, 0xfa, 0xf7, 0xaf, 0xfe, 0x00, 0x28, + 0x00, 0xd1, 0x7b, 0xe7, 0xc6, 0xe4, 0x08, 0x9b, 0x00, 0x2b, 0x2b, 0xd0, + 0xd4, 0x23, 0x14, 0x9a, 0xdb, 0x04, 0x9a, 0x42, 0x26, 0xd8, 0x28, 0x00, + 0x21, 0x00, 0x2d, 0x4a, 0x2d, 0x4b, 0xfa, 0xf7, 0x8d, 0xfe, 0x00, 0x28, + 0x17, 0xd0, 0x28, 0x00, 0x21, 0x00, 0xfa, 0xf7, 0xeb, 0xfe, 0x00, 0x28, + 0x00, 0xd1, 0x01, 0x30, 0xfa, 0xf7, 0xa6, 0xfe, 0x0f, 0x9a, 0x05, 0x00, + 0x0b, 0x00, 0x0c, 0x00, 0x00, 0x2a, 0x22, 0xd1, 0x80, 0x22, 0x12, 0x06, + 0x8b, 0x18, 0x18, 0x90, 0x19, 0x93, 0x18, 0x9a, 0x19, 0x9b, 0x10, 0x92, + 0x11, 0x93, 0xd6, 0x22, 0x11, 0x9b, 0xd2, 0x04, 0x9b, 0x18, 0x14, 0x9a, + 0x9b, 0x1a, 0x11, 0x93, 0x12, 0x98, 0x13, 0x99, 0x10, 0x9e, 0x11, 0x9f, + 0x02, 0xf0, 0x10, 0xfc, 0x02, 0x00, 0x0b, 0x00, 0x30, 0x00, 0x39, 0x00, + 0xfa, 0xf7, 0x0f, 0xfe, 0x12, 0x9a, 0x13, 0x9b, 0xfa, 0xf7, 0xe4, 0xfd, + 0x06, 0x00, 0x0f, 0x00, 0x8f, 0xe7, 0x02, 0x00, 0x18, 0x92, 0x19, 0x93, + 0xdd, 0xe7, 0x11, 0x4b, 0xfa, 0xf7, 0x4c, 0xfe, 0xb1, 0xe7, 0xc0, 0x46, + 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xf0, 0x3f, + 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, 0xb0, 0xfc, + 0xff, 0xff, 0x9f, 0x7c, 0xff, 0xff, 0xef, 0x7f, 0x00, 0x00, 0xe0, 0x3f, + 0x00, 0x00, 0xf0, 0xbf, 0x95, 0x35, 0xa0, 0x94, 0xff, 0xff, 0xdf, 0x3f, + 0x35, 0xe5, 0xaf, 0x35, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xdf, 0x41, + 0xff, 0xff, 0xcf, 0x3f, 0x10, 0xb5, 0x02, 0x4b, 0xff, 0xf7, 0xe4, 0xf9, + 0x10, 0xbd, 0xc0, 0x46, 0xa4, 0x0a, 0x00, 0x20, 0x70, 0xb5, 0x0d, 0x00, + 0x16, 0x00, 0x04, 0x00, 0xf8, 0xf7, 0x1e, 0xfc, 0x33, 0x00, 0x2a, 0x00, + 0x21, 0x00, 0xff, 0xf7, 0xd5, 0xf9, 0x70, 0xbd, 0x70, 0xb5, 0x0d, 0x00, + 0x04, 0x00, 0xf8, 0xf7, 0x13, 0xfc, 0x2a, 0x00, 0x21, 0x00, 0x02, 0x4b, + 0xff, 0xf7, 0xca, 0xf9, 0x70, 0xbd, 0xc0, 0x46, 0xa4, 0x0a, 0x00, 0x20, + 0xf8, 0xb5, 0x16, 0x00, 0x04, 0x00, 0x0d, 0x00, 0xf8, 0xf7, 0x04, 0xfc, + 0x33, 0x00, 0x2a, 0x00, 0x21, 0x00, 0xff, 0xf7, 0xbb, 0xf9, 0x06, 0x00, + 0x0c, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x30, 0x00, 0x21, 0x00, 0xfa, 0xf7, + 0x10, 0xfe, 0x00, 0x28, 0x0d, 0xd0, 0x1d, 0x48, 0x00, 0x2c, 0x06, 0xda, + 0xff, 0xf7, 0x4c, 0xf8, 0x80, 0x23, 0x1b, 0x06, 0xc5, 0x18, 0x28, 0x1c, + 0xf8, 0xbd, 0xff, 0xf7, 0x45, 0xf8, 0x05, 0x1c, 0xf9, 0xe7, 0x21, 0x00, + 0x30, 0x00, 0xfa, 0xf7, 0x8f, 0xfe, 0x47, 0x00, 0x7f, 0x08, 0x05, 0x1c, + 0x13, 0x49, 0x38, 0x1c, 0x03, 0xf0, 0x56, 0xfd, 0x00, 0x28, 0xec, 0xd1, + 0x10, 0x49, 0x38, 0x1c, 0x03, 0xf0, 0x48, 0xfd, 0x00, 0x28, 0xe6, 0xd1, + 0x01, 0x22, 0x64, 0x00, 0x64, 0x08, 0x30, 0x00, 0x21, 0x00, 0x0c, 0x4b, + 0x52, 0x42, 0xfa, 0xf7, 0xe4, 0xfd, 0x00, 0x28, 0x08, 0xd1, 0x01, 0x22, + 0x30, 0x00, 0x21, 0x00, 0x07, 0x4b, 0x52, 0x42, 0xfa, 0xf7, 0xc6, 0xfd, + 0x00, 0x28, 0xd2, 0xd0, 0xf8, 0xf7, 0xbe, 0xfb, 0x22, 0x23, 0x03, 0x60, + 0xcd, 0xe7, 0xc0, 0x46, 0x11, 0xfd, 0x00, 0x10, 0xff, 0xff, 0x7f, 0x7f, + 0xff, 0xff, 0xef, 0x7f, 0xf8, 0xb5, 0x04, 0x00, 0x0d, 0x00, 0xf8, 0xf7, + 0xaf, 0xfb, 0x2a, 0x00, 0x21, 0x00, 0x23, 0x4b, 0xff, 0xf7, 0x66, 0xf9, + 0x06, 0x00, 0x0c, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x30, 0x00, 0x21, 0x00, + 0xfa, 0xf7, 0xbb, 0xfd, 0x00, 0x28, 0x0d, 0xd0, 0x1d, 0x48, 0x00, 0x2c, + 0x06, 0xda, 0xfe, 0xf7, 0xf7, 0xff, 0x80, 0x23, 0x1b, 0x06, 0xc5, 0x18, + 0x28, 0x1c, 0xf8, 0xbd, 0xfe, 0xf7, 0xf0, 0xff, 0x05, 0x1c, 0xf9, 0xe7, + 0x21, 0x00, 0x30, 0x00, 0xfa, 0xf7, 0x3a, 0xfe, 0x47, 0x00, 0x7f, 0x08, + 0x05, 0x1c, 0x14, 0x49, 0x38, 0x1c, 0x03, 0xf0, 0x01, 0xfd, 0x00, 0x28, + 0xec, 0xd1, 0x11, 0x49, 0x38, 0x1c, 0x03, 0xf0, 0xf3, 0xfc, 0x00, 0x28, + 0xe6, 0xd1, 0x01, 0x22, 0x64, 0x00, 0x64, 0x08, 0x30, 0x00, 0x21, 0x00, + 0x0c, 0x4b, 0x52, 0x42, 0xfa, 0xf7, 0x8f, 0xfd, 0x00, 0x28, 0x08, 0xd1, + 0x01, 0x22, 0x30, 0x00, 0x21, 0x00, 0x08, 0x4b, 0x52, 0x42, 0xfa, 0xf7, + 0x71, 0xfd, 0x00, 0x28, 0xd2, 0xd0, 0xf8, 0xf7, 0x69, 0xfb, 0x22, 0x23, + 0x03, 0x60, 0xcd, 0xe7, 0xa4, 0x0a, 0x00, 0x20, 0x11, 0xfd, 0x00, 0x10, + 0xff, 0xff, 0x7f, 0x7f, 0xff, 0xff, 0xef, 0x7f, 0xf0, 0xb5, 0x87, 0xb0, + 0x1e, 0x00, 0x05, 0x90, 0x01, 0x91, 0x02, 0x92, 0x01, 0x2b, 0x45, 0xd0, + 0x0b, 0x00, 0x24, 0x2e, 0x42, 0xd8, 0x3f, 0x4a, 0x08, 0x21, 0x94, 0x46, + 0x1a, 0x00, 0x60, 0x46, 0x14, 0x78, 0x01, 0x33, 0x00, 0x5d, 0x1d, 0x00, + 0x07, 0x00, 0x0f, 0x40, 0x08, 0x42, 0xf5, 0xd1, 0x2d, 0x2c, 0x3a, 0xd1, + 0x01, 0x27, 0x1c, 0x78, 0x95, 0x1c, 0x00, 0x2e, 0x65, 0xd0, 0x10, 0x2e, + 0x09, 0xd1, 0x30, 0x2c, 0x07, 0xd1, 0x20, 0x22, 0x2b, 0x78, 0x93, 0x43, + 0x58, 0x2b, 0x57, 0xd1, 0x10, 0x26, 0x6c, 0x78, 0x02, 0x35, 0x30, 0x4b, + 0x31, 0x00, 0xfb, 0x18, 0x18, 0x00, 0x03, 0x93, 0xfa, 0xf7, 0x6c, 0xfa, + 0x00, 0x23, 0x01, 0x22, 0x84, 0x46, 0x18, 0x00, 0x04, 0x91, 0x52, 0x42, + 0x21, 0x00, 0x30, 0x39, 0x09, 0x29, 0x1d, 0xd8, 0x0c, 0x00, 0xa6, 0x42, + 0x28, 0xdd, 0x00, 0x2b, 0x24, 0xdb, 0x13, 0x00, 0x84, 0x45, 0x06, 0xd3, + 0x02, 0xd1, 0x04, 0x99, 0xa1, 0x42, 0x02, 0xdb, 0x01, 0x23, 0x70, 0x43, + 0x20, 0x18, 0x2c, 0x78, 0x01, 0x35, 0xe9, 0xe7, 0xfd, 0xf7, 0x29, 0xfc, + 0x16, 0x23, 0x03, 0x60, 0x00, 0x20, 0x07, 0xb0, 0xf0, 0xbd, 0x2b, 0x2c, + 0xc5, 0xd1, 0x1c, 0x78, 0x95, 0x1c, 0xc2, 0xe7, 0x21, 0x00, 0x41, 0x39, + 0x19, 0x29, 0x01, 0xd8, 0x37, 0x3c, 0xdc, 0xe7, 0x21, 0x00, 0x61, 0x39, + 0x19, 0x29, 0x03, 0xd8, 0x57, 0x3c, 0xd6, 0xe7, 0x13, 0x00, 0xe2, 0xe7, + 0x00, 0x2b, 0x09, 0xda, 0x22, 0x23, 0x05, 0x9a, 0x03, 0x98, 0x13, 0x60, + 0x02, 0x9b, 0x00, 0x2b, 0xe1, 0xd0, 0x6b, 0x1e, 0x01, 0x93, 0x07, 0xe0, + 0x00, 0x2f, 0x00, 0xd0, 0x40, 0x42, 0x02, 0x9a, 0x00, 0x2a, 0xd8, 0xd0, + 0x00, 0x2b, 0xf4, 0xd1, 0x02, 0x9b, 0x01, 0x9a, 0x1a, 0x60, 0xd2, 0xe7, + 0x30, 0x24, 0x00, 0x2e, 0xa7, 0xd1, 0x08, 0x36, 0xa5, 0xe7, 0x30, 0x2c, + 0x9b, 0xd0, 0x0a, 0x26, 0xa1, 0xe7, 0xc0, 0x46, 0x29, 0x02, 0x01, 0x10, + 0xff, 0xff, 0xff, 0x7f, 0x10, 0xb5, 0xff, 0xf7, 0x6f, 0xff, 0x10, 0xbd, + 0x70, 0xb5, 0x0d, 0x00, 0x16, 0x00, 0x04, 0x00, 0xf8, 0xf7, 0xc6, 0xfa, + 0x33, 0x00, 0x2a, 0x00, 0x21, 0x00, 0xff, 0xf7, 0x63, 0xff, 0x70, 0xbd, + 0x70, 0xb5, 0x0d, 0x00, 0x16, 0x00, 0x04, 0x00, 0xf8, 0xf7, 0xba, 0xfa, + 0x33, 0x00, 0x2a, 0x00, 0x21, 0x00, 0xff, 0xf7, 0x57, 0xff, 0x70, 0xbd, + 0x70, 0xb5, 0x05, 0x00, 0x0e, 0x00, 0xf8, 0xf7, 0xaf, 0xfa, 0x04, 0x1e, + 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, 0x01, 0xd1, 0xfd, 0xf7, 0x4a, 0xfc, + 0x33, 0x00, 0x2a, 0x00, 0x20, 0x00, 0xa1, 0x68, 0x02, 0xf0, 0x20, 0xfe, + 0x70, 0xbd, 0x70, 0xb5, 0x04, 0x00, 0x0d, 0x00, 0x16, 0x00, 0x00, 0x28, + 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, 0x01, 0xd1, 0xfd, 0xf7, 0x38, 0xfc, + 0x33, 0x00, 0x2a, 0x00, 0x20, 0x00, 0xa1, 0x68, 0x02, 0xf0, 0x0e, 0xfe, + 0x70, 0xbd, 0x30, 0xb5, 0x14, 0x00, 0x05, 0x00, 0x1a, 0x00, 0x9d, 0xb0, + 0x00, 0x2c, 0x05, 0xda, 0x8b, 0x23, 0x03, 0x60, 0x01, 0x20, 0x40, 0x42, + 0x1d, 0xb0, 0x30, 0xbd, 0x82, 0x23, 0x68, 0x46, 0x9b, 0x00, 0x83, 0x81, + 0x00, 0x23, 0x00, 0x91, 0x04, 0x91, 0x9c, 0x42, 0x00, 0xd0, 0x63, 0x1e, + 0x02, 0x93, 0x05, 0x93, 0x01, 0x23, 0x69, 0x46, 0x5b, 0x42, 0xcb, 0x81, + 0x28, 0x00, 0x20, 0x9b, 0x02, 0xf0, 0x5e, 0xfc, 0x43, 0x1c, 0x01, 0xda, + 0x8b, 0x23, 0x2b, 0x60, 0x00, 0x2c, 0xe3, 0xd0, 0x00, 0x23, 0x00, 0x9a, + 0x13, 0x70, 0xdf, 0xe7, 0xf7, 0xb5, 0x0d, 0x00, 0x16, 0x00, 0x1f, 0x00, + 0x04, 0x00, 0xf8, 0xf7, 0x5d, 0xfa, 0x33, 0x00, 0x2a, 0x00, 0x00, 0x97, + 0x21, 0x00, 0xff, 0xf7, 0xc8, 0xff, 0xfe, 0xbd, 0x70, 0xb5, 0x04, 0x00, + 0x08, 0x00, 0x11, 0x00, 0x1a, 0x00, 0x00, 0x23, 0x05, 0x4d, 0x2b, 0x60, + 0x03, 0xf0, 0x5f, 0xfb, 0x43, 0x1c, 0x03, 0xd1, 0x2b, 0x68, 0x00, 0x2b, + 0x00, 0xd0, 0x23, 0x60, 0x70, 0xbd, 0xc0, 0x46, 0x20, 0x0e, 0x00, 0x20, + 0x00, 0x23, 0x70, 0xb5, 0x06, 0x4d, 0x04, 0x00, 0x08, 0x00, 0x2b, 0x60, + 0x03, 0xf0, 0x50, 0xfb, 0x43, 0x1c, 0x03, 0xd1, 0x2b, 0x68, 0x00, 0x2b, + 0x00, 0xd0, 0x23, 0x60, 0x70, 0xbd, 0xc0, 0x46, 0x20, 0x0e, 0x00, 0x20, + 0xf0, 0xb5, 0x06, 0x00, 0x0b, 0x69, 0x32, 0x69, 0x87, 0xb0, 0x00, 0x20, + 0x03, 0x91, 0x9a, 0x42, 0x65, 0xdb, 0x01, 0x3b, 0x9c, 0x00, 0x00, 0x93, + 0x0b, 0x00, 0x14, 0x33, 0x05, 0x93, 0x1b, 0x19, 0x04, 0x93, 0x33, 0x00, + 0x14, 0x33, 0x02, 0x93, 0x1c, 0x19, 0x04, 0x9b, 0x27, 0x68, 0x1b, 0x68, + 0x38, 0x00, 0x5d, 0x1c, 0x29, 0x00, 0x01, 0x93, 0xfa, 0xf7, 0x52, 0xf9, + 0x01, 0x90, 0xaf, 0x42, 0x24, 0xd3, 0x00, 0x25, 0xac, 0x46, 0x02, 0x98, + 0x05, 0x9f, 0x08, 0xcf, 0x01, 0x9a, 0x99, 0xb2, 0x51, 0x43, 0x1b, 0x0c, + 0x53, 0x43, 0x49, 0x19, 0x0a, 0x0c, 0x9b, 0x18, 0x02, 0x68, 0x89, 0xb2, + 0x92, 0xb2, 0x62, 0x44, 0x52, 0x1a, 0x01, 0x68, 0x1d, 0x0c, 0x09, 0x0c, + 0x9b, 0xb2, 0xcb, 0x1a, 0x11, 0x14, 0x5b, 0x18, 0x19, 0x14, 0x92, 0xb2, + 0x1b, 0x04, 0x1a, 0x43, 0x04, 0x9b, 0x8c, 0x46, 0x04, 0xc0, 0xbb, 0x42, + 0xe1, 0xd2, 0x23, 0x68, 0x00, 0x2b, 0x30, 0xd0, 0x30, 0x00, 0x03, 0x99, + 0x02, 0xf0, 0xe2, 0xf8, 0x00, 0x28, 0x21, 0xdb, 0x30, 0x00, 0x00, 0x24, + 0x01, 0x9b, 0x03, 0x99, 0x01, 0x33, 0x01, 0x93, 0x14, 0x30, 0x14, 0x31, + 0x03, 0x68, 0x20, 0xc9, 0x9a, 0xb2, 0x14, 0x19, 0xaa, 0xb2, 0xa2, 0x1a, + 0x1b, 0x0c, 0x2d, 0x0c, 0x14, 0x14, 0x5b, 0x1b, 0x1b, 0x19, 0x1c, 0x14, + 0x92, 0xb2, 0x1b, 0x04, 0x13, 0x43, 0x08, 0xc0, 0x04, 0x9b, 0x8b, 0x42, + 0xec, 0xd2, 0x00, 0x9b, 0x02, 0x9a, 0x9b, 0x00, 0xd3, 0x18, 0x1a, 0x68, + 0x00, 0x2a, 0x15, 0xd0, 0x01, 0x98, 0x07, 0xb0, 0xf0, 0xbd, 0x23, 0x68, + 0x00, 0x2b, 0x06, 0xd1, 0x00, 0x9b, 0x01, 0x3b, 0x00, 0x93, 0x02, 0x9b, + 0x04, 0x3c, 0xa3, 0x42, 0xf5, 0xd3, 0x00, 0x9b, 0x33, 0x61, 0xc7, 0xe7, + 0x1a, 0x68, 0x00, 0x2a, 0x06, 0xd1, 0x00, 0x9a, 0x01, 0x3a, 0x00, 0x92, + 0x02, 0x9a, 0x04, 0x3b, 0x9a, 0x42, 0xf5, 0xd3, 0x00, 0x9b, 0x33, 0x61, + 0xe2, 0xe7, 0xf0, 0xb5, 0x9d, 0xb0, 0x02, 0x92, 0x03, 0x93, 0x02, 0x9b, + 0x03, 0x9c, 0x08, 0x93, 0x09, 0x94, 0x44, 0x6a, 0x07, 0x00, 0x25, 0x9d, + 0x00, 0x2c, 0x0e, 0xd1, 0x10, 0x20, 0xfd, 0xf7, 0x0c, 0xfc, 0x02, 0x1e, + 0x78, 0x62, 0x04, 0xd1, 0xea, 0x21, 0xc8, 0x4b, 0xc8, 0x48, 0xfa, 0xf7, + 0x71, 0xf8, 0x44, 0x60, 0x84, 0x60, 0x04, 0x60, 0xc4, 0x60, 0x7b, 0x6a, + 0x19, 0x68, 0x00, 0x29, 0x0a, 0xd0, 0x5a, 0x68, 0x01, 0x23, 0x93, 0x40, + 0x4a, 0x60, 0x8b, 0x60, 0x38, 0x00, 0x01, 0xf0, 0xed, 0xfd, 0x00, 0x22, + 0x7b, 0x6a, 0x1a, 0x60, 0x03, 0x9b, 0x00, 0x2b, 0x20, 0xda, 0x01, 0x23, + 0x2b, 0x60, 0x03, 0x9b, 0x5b, 0x00, 0x5b, 0x08, 0x09, 0x93, 0x09, 0x9d, + 0xb9, 0x4b, 0xb9, 0x4a, 0x2b, 0x40, 0x93, 0x42, 0x17, 0xd1, 0xb8, 0x4b, + 0x24, 0x9a, 0x28, 0x03, 0x13, 0x60, 0x02, 0x9b, 0x00, 0x0b, 0x18, 0x43, + 0x01, 0xd1, 0x00, 0xf0, 0xc0, 0xfd, 0xb4, 0x48, 0x26, 0x9b, 0x06, 0x90, + 0x00, 0x2b, 0x02, 0xd0, 0xb2, 0x4b, 0x26, 0x9a, 0x13, 0x60, 0x06, 0x98, + 0x1d, 0xb0, 0xf0, 0xbd, 0x00, 0x23, 0x2b, 0x60, 0xe1, 0xe7, 0x08, 0x9b, + 0x09, 0x9c, 0x12, 0x93, 0x13, 0x94, 0x12, 0x98, 0x13, 0x99, 0x00, 0x22, + 0x00, 0x23, 0xfa, 0xf7, 0x3f, 0xfb, 0x04, 0x1e, 0x09, 0xd0, 0x01, 0x23, + 0x24, 0x9a, 0x13, 0x60, 0xa7, 0x4b, 0x06, 0x93, 0x26, 0x9b, 0x00, 0x2b, + 0xe5, 0xd0, 0xa6, 0x4b, 0xe1, 0xe7, 0x1a, 0xab, 0x01, 0x93, 0x1b, 0xab, + 0x00, 0x93, 0x38, 0x00, 0x12, 0x9a, 0x13, 0x9b, 0x02, 0xf0, 0x56, 0xf9, + 0x6e, 0x00, 0x05, 0x90, 0x76, 0x0d, 0x00, 0xd1, 0x7c, 0xe0, 0x12, 0x98, + 0x13, 0x99, 0x13, 0x9b, 0x9d, 0x4a, 0x1b, 0x03, 0x1b, 0x0b, 0x1a, 0x43, + 0x11, 0x00, 0x9c, 0x4b, 0x18, 0x94, 0xf6, 0x18, 0x00, 0x22, 0x9b, 0x4b, + 0xfa, 0xf7, 0xa3, 0xfa, 0x9a, 0x4a, 0x9b, 0x4b, 0xfa, 0xf7, 0xcf, 0xfa, + 0x9a, 0x4a, 0x9b, 0x4b, 0xfa, 0xf7, 0xa4, 0xfa, 0x04, 0x00, 0x30, 0x00, + 0x0d, 0x00, 0xfa, 0xf7, 0x3f, 0xfb, 0x98, 0x4a, 0x98, 0x4b, 0xfa, 0xf7, + 0xc2, 0xfa, 0x02, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x29, 0x00, 0xfa, 0xf7, + 0x95, 0xfa, 0x04, 0x00, 0x0d, 0x00, 0xfa, 0xf7, 0x49, 0xfb, 0x00, 0x22, + 0x02, 0x90, 0x00, 0x23, 0x20, 0x00, 0x29, 0x00, 0xfa, 0xf7, 0xfc, 0xfa, + 0x00, 0x28, 0x0b, 0xd0, 0x02, 0x98, 0xfa, 0xf7, 0x25, 0xfb, 0x2b, 0x00, + 0x22, 0x00, 0xfa, 0xf7, 0xeb, 0xfa, 0x43, 0x42, 0x58, 0x41, 0x02, 0x9b, + 0x1b, 0x1a, 0x02, 0x93, 0x01, 0x23, 0x16, 0x93, 0x02, 0x9b, 0x16, 0x2b, + 0x0f, 0xd8, 0x12, 0x98, 0x13, 0x99, 0xda, 0x00, 0x84, 0x4b, 0x9b, 0x18, + 0x1a, 0x68, 0x5b, 0x68, 0xfa, 0xf7, 0xe0, 0xfa, 0x00, 0x28, 0x49, 0xd0, + 0x02, 0x9b, 0x01, 0x3b, 0x02, 0x93, 0x00, 0x23, 0x16, 0x93, 0x1a, 0x9b, + 0x9e, 0x1b, 0x00, 0x23, 0x0a, 0x93, 0x33, 0x00, 0x01, 0x3b, 0x0d, 0x93, + 0x04, 0xd5, 0x01, 0x23, 0x9b, 0x1b, 0x0a, 0x93, 0x00, 0x23, 0x0d, 0x93, + 0x02, 0x9b, 0x00, 0x2b, 0x36, 0xdb, 0x02, 0x9a, 0x0d, 0x9b, 0x94, 0x46, + 0x63, 0x44, 0x0d, 0x93, 0x00, 0x23, 0x15, 0x92, 0x0e, 0x93, 0x22, 0x9b, + 0x01, 0x24, 0x09, 0x2b, 0x64, 0xd8, 0x05, 0x2b, 0x02, 0xdd, 0x00, 0x24, + 0x04, 0x3b, 0x22, 0x93, 0x22, 0x9b, 0x98, 0x1e, 0x03, 0x28, 0x64, 0xd8, + 0x03, 0xf0, 0xd0, 0xfa, 0x29, 0x38, 0x36, 0x58, 0x1a, 0x9b, 0x1b, 0x9a, + 0x9e, 0x18, 0x69, 0x4b, 0xf2, 0x18, 0x20, 0x2a, 0x0f, 0xdd, 0x40, 0x23, + 0x9b, 0x1a, 0x9d, 0x40, 0x66, 0x4b, 0x02, 0x98, 0xf3, 0x18, 0xd8, 0x40, + 0x28, 0x43, 0xfa, 0xf7, 0xc9, 0xfa, 0x01, 0x23, 0x63, 0x4c, 0x01, 0x3e, + 0x09, 0x19, 0x18, 0x93, 0x76, 0xe7, 0x20, 0x23, 0x02, 0x98, 0x9b, 0x1a, + 0x98, 0x40, 0xf2, 0xe7, 0x16, 0x90, 0xb8, 0xe7, 0x0a, 0x9b, 0x02, 0x9a, + 0x9b, 0x1a, 0x0a, 0x93, 0x53, 0x42, 0x0e, 0x93, 0x00, 0x23, 0x15, 0x93, + 0xc7, 0xe7, 0x00, 0x23, 0x0f, 0x93, 0x23, 0x9b, 0x0c, 0x93, 0x07, 0x93, + 0x00, 0x2b, 0x13, 0xdc, 0x01, 0x23, 0x1a, 0x00, 0x0c, 0x93, 0x07, 0x93, + 0x23, 0x92, 0x0d, 0xe0, 0x01, 0x23, 0xf1, 0xe7, 0x00, 0x23, 0x23, 0x9a, + 0x0f, 0x93, 0x94, 0x46, 0x02, 0x9b, 0x63, 0x44, 0x0c, 0x93, 0x01, 0x33, + 0x07, 0x93, 0x00, 0x2b, 0x00, 0xdc, 0x01, 0x23, 0x00, 0x22, 0x78, 0x6a, + 0x42, 0x60, 0x04, 0x32, 0x15, 0x00, 0x14, 0x35, 0x41, 0x68, 0x9d, 0x42, + 0x19, 0xd9, 0x38, 0x00, 0x01, 0xf0, 0x90, 0xfc, 0x06, 0x90, 0x00, 0x28, + 0x17, 0xd1, 0xd5, 0x21, 0x02, 0x00, 0x44, 0x4b, 0x49, 0x00, 0xcb, 0xe6, + 0x01, 0x23, 0xde, 0xe7, 0x00, 0x23, 0x0f, 0x94, 0x22, 0x93, 0x01, 0x3b, + 0x0c, 0x93, 0x07, 0x93, 0x00, 0x22, 0x13, 0x33, 0xd0, 0xe7, 0x01, 0x23, + 0x0f, 0x93, 0x02, 0x3b, 0xf6, 0xe7, 0x01, 0x31, 0x41, 0x60, 0x52, 0x00, + 0xdc, 0xe7, 0x7b, 0x6a, 0x06, 0x9a, 0x1a, 0x60, 0x07, 0x9b, 0x0e, 0x2b, + 0x00, 0xd9, 0xec, 0xe0, 0x00, 0x2c, 0x00, 0xd1, 0xe9, 0xe0, 0x02, 0x9b, + 0x00, 0x2b, 0x69, 0xdd, 0x1a, 0x00, 0x0f, 0x21, 0x2d, 0x4b, 0x0a, 0x40, + 0xd2, 0x00, 0x9b, 0x18, 0x1d, 0x68, 0x5e, 0x68, 0x02, 0x9b, 0x1c, 0x11, + 0x02, 0x23, 0x10, 0x93, 0x02, 0x9b, 0xdb, 0x05, 0x0b, 0xd5, 0x2c, 0x4b, + 0x0c, 0x40, 0x1a, 0x6a, 0x5b, 0x6a, 0x12, 0x98, 0x13, 0x99, 0xfa, 0xf7, + 0xba, 0xf9, 0x03, 0x23, 0x08, 0x90, 0x09, 0x91, 0x10, 0x93, 0x26, 0x4b, + 0x14, 0x93, 0x00, 0x2c, 0x08, 0xd1, 0x08, 0x98, 0x09, 0x99, 0x2a, 0x00, + 0x33, 0x00, 0xfa, 0xf7, 0xac, 0xf9, 0x08, 0x90, 0x09, 0x91, 0x5d, 0xe0, + 0x01, 0x23, 0x1c, 0x42, 0x0b, 0xd0, 0x10, 0x9b, 0x28, 0x00, 0x01, 0x33, + 0x10, 0x93, 0x14, 0x9b, 0x31, 0x00, 0x1a, 0x68, 0x5b, 0x68, 0xfa, 0xf7, + 0xba, 0xf9, 0x05, 0x00, 0x0e, 0x00, 0x14, 0x9b, 0x64, 0x10, 0x08, 0x33, + 0xe0, 0xe7, 0xc0, 0x46, 0x36, 0x03, 0x01, 0x10, 0x4d, 0x03, 0x01, 0x10, + 0x00, 0x00, 0xf0, 0x7f, 0x0f, 0x27, 0x00, 0x00, 0x32, 0x03, 0x01, 0x10, + 0x35, 0x03, 0x01, 0x10, 0xac, 0x01, 0x01, 0x10, 0xad, 0x01, 0x01, 0x10, + 0x00, 0x00, 0xf0, 0x3f, 0x01, 0xfc, 0xff, 0xff, 0x00, 0x00, 0xf8, 0x3f, + 0x61, 0x43, 0x6f, 0x63, 0xa7, 0x87, 0xd2, 0x3f, 0xb3, 0xc8, 0x60, 0x8b, + 0x28, 0x8a, 0xc6, 0x3f, 0xfb, 0x79, 0x9f, 0x50, 0x13, 0x44, 0xd3, 0x3f, + 0x70, 0x04, 0x01, 0x10, 0x32, 0x04, 0x00, 0x00, 0x12, 0x04, 0x00, 0x00, + 0x00, 0x00, 0x10, 0xfe, 0x7c, 0x03, 0x01, 0x10, 0x48, 0x04, 0x01, 0x10, + 0x02, 0x23, 0x10, 0x93, 0x02, 0x9b, 0x00, 0x2b, 0x16, 0xd0, 0x12, 0x98, + 0x13, 0x99, 0x5c, 0x42, 0x0f, 0x23, 0xb6, 0x4a, 0x23, 0x40, 0xdb, 0x00, + 0xd3, 0x18, 0x1a, 0x68, 0x5b, 0x68, 0xfa, 0xf7, 0x74, 0xf9, 0x01, 0x26, + 0x00, 0x23, 0x08, 0x90, 0x09, 0x91, 0xb1, 0x4d, 0x24, 0x11, 0x00, 0x2c, + 0x00, 0xd0, 0x94, 0xe0, 0x00, 0x2b, 0x9e, 0xd1, 0x16, 0x9b, 0x00, 0x2b, + 0x00, 0xd1, 0x9b, 0xe0, 0x08, 0x9c, 0x09, 0x9d, 0x00, 0x22, 0x20, 0x00, + 0x29, 0x00, 0xaa, 0x4b, 0xfa, 0xf7, 0xa8, 0xf9, 0x00, 0x28, 0x00, 0xd1, + 0x90, 0xe0, 0x07, 0x9b, 0x00, 0x2b, 0x00, 0xd1, 0x8c, 0xe0, 0x0c, 0x9b, + 0x00, 0x2b, 0x46, 0xdd, 0x02, 0x9b, 0x00, 0x22, 0x20, 0x00, 0x29, 0x00, + 0x5e, 0x1e, 0xa2, 0x4b, 0xfa, 0xf7, 0x4b, 0xf9, 0x10, 0x9b, 0x08, 0x90, + 0x09, 0x91, 0x01, 0x33, 0x10, 0x93, 0x0c, 0x9b, 0x10, 0x98, 0x08, 0x9c, + 0x09, 0x9d, 0x14, 0x93, 0xfa, 0xf7, 0xb8, 0xf9, 0x22, 0x00, 0x2b, 0x00, + 0xfa, 0xf7, 0x3b, 0xf9, 0x00, 0x22, 0x99, 0x4b, 0xfa, 0xf7, 0x10, 0xf9, + 0x10, 0x90, 0x11, 0x91, 0x10, 0x9a, 0x11, 0x9b, 0x08, 0x92, 0x09, 0x93, + 0x95, 0x4a, 0x11, 0x9b, 0x94, 0x46, 0x63, 0x44, 0x17, 0x93, 0x09, 0x93, + 0x14, 0x9b, 0x00, 0x2b, 0x61, 0xd1, 0x00, 0x22, 0x20, 0x00, 0x29, 0x00, + 0x90, 0x4b, 0xfa, 0xf7, 0xf2, 0xf8, 0x08, 0x9a, 0x17, 0x9b, 0x04, 0x00, + 0x0d, 0x00, 0xfa, 0xf7, 0x7d, 0xf9, 0x00, 0x28, 0x00, 0xd0, 0xaf, 0xe2, + 0x8b, 0x48, 0x11, 0x99, 0x84, 0x46, 0x61, 0x44, 0x0b, 0x00, 0x20, 0x00, + 0x29, 0x00, 0x08, 0x9a, 0xfa, 0xf7, 0x5a, 0xf9, 0x00, 0x28, 0x00, 0xd0, + 0x9f, 0xe2, 0x12, 0x9b, 0x13, 0x9c, 0x08, 0x93, 0x09, 0x94, 0x1b, 0x9b, + 0x00, 0x2b, 0x00, 0xda, 0x72, 0xe1, 0x02, 0x9a, 0x0e, 0x2a, 0x00, 0xdd, + 0x6e, 0xe1, 0x78, 0x4b, 0xd2, 0x00, 0x9b, 0x18, 0x5c, 0x68, 0x1b, 0x68, + 0x0a, 0x93, 0x0b, 0x94, 0x23, 0x9b, 0x00, 0x2b, 0x00, 0xdb, 0xf7, 0xe0, + 0x07, 0x9b, 0x00, 0x2b, 0x00, 0xdd, 0xf3, 0xe0, 0x00, 0xd0, 0x82, 0xe2, + 0x0a, 0x98, 0x0b, 0x99, 0x00, 0x22, 0x74, 0x4b, 0xfa, 0xf7, 0xe9, 0xf8, + 0x08, 0x9a, 0x09, 0x9b, 0xfa, 0xf7, 0x3e, 0xf9, 0x07, 0x9e, 0x35, 0x00, + 0x00, 0x28, 0x00, 0xd0, 0x59, 0xe2, 0x06, 0x9b, 0x06, 0x9a, 0x01, 0x33, + 0x08, 0x93, 0x31, 0x23, 0x13, 0x70, 0x02, 0x9b, 0x01, 0x33, 0x02, 0x93, + 0x54, 0xe2, 0x34, 0x42, 0x07, 0xd0, 0x10, 0x9b, 0x01, 0x33, 0x10, 0x93, + 0x2a, 0x68, 0x6b, 0x68, 0xfa, 0xf7, 0xcd, 0xf8, 0x33, 0x00, 0x64, 0x10, + 0x08, 0x35, 0x5a, 0xe7, 0x02, 0x9e, 0x07, 0x9b, 0x80, 0xe7, 0x14, 0x9b, + 0x0f, 0x99, 0x5a, 0x1e, 0x59, 0x4b, 0xd2, 0x00, 0x9b, 0x18, 0x1a, 0x68, + 0x5b, 0x68, 0x00, 0x29, 0x51, 0xd0, 0x00, 0x20, 0x5d, 0x49, 0xfa, 0xf7, + 0x9a, 0xf8, 0x08, 0x9a, 0x09, 0x9b, 0xfa, 0xf7, 0x84, 0xf8, 0x06, 0x9a, + 0x06, 0x9b, 0x94, 0x46, 0x17, 0x93, 0x14, 0x9b, 0x10, 0x90, 0x11, 0x91, + 0x63, 0x44, 0x19, 0x93, 0x29, 0x00, 0x20, 0x00, 0xfa, 0xf7, 0x38, 0xf9, + 0x14, 0x90, 0xfa, 0xf7, 0x1d, 0xf9, 0x02, 0x00, 0x0b, 0x00, 0x20, 0x00, + 0x29, 0x00, 0xfa, 0xf7, 0x6e, 0xf8, 0x17, 0x9b, 0x17, 0x9a, 0x01, 0x33, + 0x08, 0x93, 0x14, 0x9b, 0x04, 0x00, 0x30, 0x33, 0x13, 0x70, 0x10, 0x9a, + 0x11, 0x9b, 0x0d, 0x00, 0xfa, 0xf7, 0xdc, 0xf8, 0x00, 0x28, 0x75, 0xd1, + 0x22, 0x00, 0x2b, 0x00, 0x00, 0x20, 0x40, 0x49, 0xfa, 0xf7, 0x59, 0xf8, + 0x10, 0x9a, 0x11, 0x9b, 0xfa, 0xf7, 0xd0, 0xf8, 0x00, 0x28, 0x00, 0xd0, + 0xd2, 0xe0, 0x19, 0x9b, 0x08, 0x9a, 0x93, 0x42, 0x00, 0xd1, 0x70, 0xe7, + 0x10, 0x98, 0x11, 0x99, 0x00, 0x22, 0x38, 0x4b, 0xfa, 0xf7, 0x77, 0xf8, + 0x36, 0x4b, 0x10, 0x90, 0x11, 0x91, 0x00, 0x22, 0x20, 0x00, 0x29, 0x00, + 0xfa, 0xf7, 0x6f, 0xf8, 0x08, 0x9b, 0x04, 0x00, 0x0d, 0x00, 0x17, 0x93, + 0xbe, 0xe7, 0x08, 0x98, 0x09, 0x99, 0xfa, 0xf7, 0x66, 0xf8, 0x06, 0x9a, + 0x06, 0x9b, 0x94, 0x46, 0x08, 0x93, 0x14, 0x9b, 0x10, 0x90, 0x11, 0x91, + 0x63, 0x44, 0x19, 0x93, 0x29, 0x00, 0x20, 0x00, 0xfa, 0xf7, 0xea, 0xf8, + 0x17, 0x90, 0xfa, 0xf7, 0xcf, 0xf8, 0x02, 0x00, 0x0b, 0x00, 0x20, 0x00, + 0x29, 0x00, 0xfa, 0xf7, 0x20, 0xf8, 0x17, 0x9b, 0x08, 0x9a, 0x30, 0x33, + 0x13, 0x70, 0x13, 0x00, 0x19, 0x9a, 0x01, 0x33, 0x04, 0x00, 0x0d, 0x00, + 0x08, 0x93, 0x93, 0x42, 0x2c, 0xd1, 0x10, 0x98, 0x11, 0x99, 0x06, 0x9a, + 0x14, 0x9b, 0x94, 0x46, 0x63, 0x44, 0x00, 0x22, 0x08, 0x93, 0x1e, 0x4b, + 0xfa, 0xf7, 0x12, 0xf8, 0x02, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x29, 0x00, + 0xfa, 0xf7, 0x94, 0xf8, 0x00, 0x28, 0x00, 0xd0, 0x80, 0xe0, 0x10, 0x9a, + 0x11, 0x9b, 0x00, 0x20, 0x16, 0x49, 0xf9, 0xf7, 0xfa, 0xff, 0x02, 0x00, + 0x0b, 0x00, 0x20, 0x00, 0x29, 0x00, 0xfa, 0xf7, 0x6f, 0xf8, 0x00, 0x28, + 0x00, 0xd1, 0x14, 0xe7, 0x08, 0x9b, 0x1a, 0x00, 0x01, 0x3a, 0x08, 0x92, + 0x12, 0x78, 0x30, 0x2a, 0xf8, 0xd0, 0x08, 0x93, 0x02, 0x96, 0x55, 0xe0, + 0x00, 0x22, 0x06, 0x4b, 0xfa, 0xf7, 0x13, 0xf8, 0x04, 0x00, 0x0d, 0x00, + 0xb2, 0xe7, 0xc0, 0x46, 0x70, 0x04, 0x01, 0x10, 0x48, 0x04, 0x01, 0x10, + 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x1c, 0x40, + 0x00, 0x00, 0xc0, 0xfc, 0x00, 0x00, 0x14, 0x40, 0x00, 0x00, 0xc0, 0x7c, + 0x00, 0x00, 0xe0, 0x3f, 0x07, 0x9b, 0x06, 0x9e, 0x01, 0x3b, 0x9b, 0x19, + 0x0c, 0x93, 0x08, 0x9c, 0x09, 0x9d, 0x0a, 0x9a, 0x0b, 0x9b, 0x20, 0x00, + 0x29, 0x00, 0xf9, 0xf7, 0xd2, 0xff, 0xfa, 0xf7, 0x7f, 0xf8, 0x07, 0x90, + 0xfa, 0xf7, 0x64, 0xf8, 0x0a, 0x9a, 0x0b, 0x9b, 0xf9, 0xf7, 0xe7, 0xff, + 0x02, 0x00, 0x0b, 0x00, 0x20, 0x00, 0x29, 0x00, 0xf9, 0xf7, 0xb1, 0xff, + 0x33, 0x00, 0x07, 0x9a, 0x01, 0x36, 0x30, 0x32, 0x1a, 0x70, 0x0c, 0x9a, + 0x08, 0x96, 0x9a, 0x42, 0x39, 0xd1, 0x02, 0x00, 0x0b, 0x00, 0xf9, 0xf7, + 0xad, 0xff, 0x0a, 0x9a, 0x0b, 0x9b, 0x04, 0x00, 0x0d, 0x00, 0xfa, 0xf7, + 0x2f, 0xf8, 0x00, 0x28, 0x1b, 0xd1, 0x0a, 0x9a, 0x0b, 0x9b, 0x20, 0x00, + 0x29, 0x00, 0xfa, 0xf7, 0x09, 0xf8, 0x00, 0x28, 0x02, 0xd0, 0x07, 0x9b, + 0xdb, 0x07, 0x10, 0xd4, 0x38, 0x00, 0x05, 0x99, 0x01, 0xf0, 0x7a, 0xfa, + 0x00, 0x23, 0x08, 0x9a, 0x02, 0x98, 0x13, 0x70, 0x24, 0x9b, 0x01, 0x30, + 0x18, 0x60, 0x26, 0x9b, 0x00, 0x2b, 0x00, 0xd1, 0xa5, 0xe4, 0x1a, 0x60, + 0xa3, 0xe4, 0x02, 0x9e, 0x08, 0x9b, 0x08, 0x93, 0x01, 0x3b, 0x1a, 0x78, + 0x39, 0x2a, 0x06, 0xd1, 0x06, 0x9a, 0x9a, 0x42, 0xf7, 0xd1, 0x30, 0x22, + 0x06, 0x99, 0x01, 0x36, 0x0a, 0x70, 0x1a, 0x78, 0x01, 0x32, 0x1a, 0x70, + 0x84, 0xe7, 0x00, 0x22, 0xaa, 0x4b, 0xf9, 0xf7, 0x9a, 0xff, 0x00, 0x22, + 0x00, 0x23, 0x04, 0x00, 0x0d, 0x00, 0xf9, 0xf7, 0xd7, 0xff, 0x00, 0x28, + 0x9b, 0xd0, 0xcf, 0xe7, 0x0f, 0x9d, 0x0e, 0x9e, 0x0a, 0x9c, 0x00, 0x2d, + 0x12, 0xd0, 0x22, 0x9a, 0x01, 0x2a, 0x66, 0xdc, 0x18, 0x9a, 0x00, 0x2a, + 0x5d, 0xd0, 0xa0, 0x4a, 0x9b, 0x18, 0x0a, 0x9a, 0x01, 0x21, 0xd2, 0x18, + 0x0a, 0x92, 0x0d, 0x9a, 0x38, 0x00, 0xd3, 0x18, 0x0d, 0x93, 0x01, 0xf0, + 0x33, 0xfb, 0x05, 0x00, 0x00, 0x2c, 0x0e, 0xdd, 0x0d, 0x9b, 0x00, 0x2b, + 0x0b, 0xdd, 0x0d, 0x9a, 0x23, 0x00, 0x94, 0x42, 0x00, 0xdd, 0x13, 0x00, + 0x0a, 0x9a, 0xe4, 0x1a, 0xd2, 0x1a, 0x0a, 0x92, 0x0d, 0x9a, 0xd3, 0x1a, + 0x0d, 0x93, 0x0e, 0x9b, 0x00, 0x2b, 0x1f, 0xd0, 0x0f, 0x9b, 0x00, 0x2b, + 0x54, 0xd0, 0x00, 0x2e, 0x11, 0xdd, 0x29, 0x00, 0x32, 0x00, 0x38, 0x00, + 0x01, 0xf0, 0xda, 0xfb, 0x05, 0x9a, 0x01, 0x00, 0x05, 0x00, 0x38, 0x00, + 0x01, 0xf0, 0x24, 0xfb, 0x05, 0x99, 0x14, 0x90, 0x38, 0x00, 0x01, 0xf0, + 0x0d, 0xfa, 0x14, 0x9b, 0x05, 0x93, 0x0e, 0x9b, 0x9a, 0x1b, 0xb3, 0x42, + 0x04, 0xd0, 0x38, 0x00, 0x05, 0x99, 0x01, 0xf0, 0xc5, 0xfb, 0x05, 0x90, + 0x01, 0x21, 0x38, 0x00, 0x01, 0xf0, 0xfa, 0xfa, 0x15, 0x9b, 0x06, 0x00, + 0x00, 0x2b, 0x31, 0xdd, 0x1a, 0x00, 0x01, 0x00, 0x38, 0x00, 0x01, 0xf0, + 0xb7, 0xfb, 0x22, 0x9b, 0x06, 0x00, 0x01, 0x2b, 0x2d, 0xdd, 0x00, 0x23, + 0x0e, 0x93, 0x33, 0x69, 0x03, 0x33, 0x9b, 0x00, 0xf3, 0x18, 0x58, 0x68, + 0x01, 0xf0, 0x9c, 0xfa, 0x20, 0x23, 0x18, 0x1a, 0x39, 0xe0, 0x36, 0x23, + 0x1a, 0x9a, 0x0e, 0x9e, 0x0a, 0x9c, 0x9b, 0x1a, 0x9d, 0xe7, 0x07, 0x9b, + 0x5e, 0x1e, 0x0e, 0x9b, 0xb3, 0x42, 0x07, 0xdb, 0x9e, 0x1b, 0x07, 0x9b, + 0x0a, 0x9c, 0x00, 0x2b, 0x93, 0xda, 0xe4, 0x1a, 0x00, 0x23, 0x90, 0xe7, + 0x0e, 0x9b, 0x15, 0x9a, 0xf3, 0x1a, 0xd3, 0x18, 0x0e, 0x96, 0x15, 0x93, + 0x00, 0x26, 0xf0, 0xe7, 0x0e, 0x9a, 0xc0, 0xe7, 0x00, 0x23, 0x0e, 0x93, + 0x22, 0x9b, 0x01, 0x2b, 0x13, 0xdc, 0x00, 0x23, 0x0e, 0x93, 0x08, 0x9b, + 0x00, 0x2b, 0x0e, 0xd1, 0x09, 0x9b, 0x1b, 0x03, 0x0b, 0xd1, 0x5d, 0x4b, + 0x09, 0x9a, 0x13, 0x42, 0x07, 0xd0, 0x0a, 0x9b, 0x01, 0x33, 0x0a, 0x93, + 0x0d, 0x9b, 0x01, 0x33, 0x0d, 0x93, 0x01, 0x23, 0x0e, 0x93, 0x15, 0x9b, + 0x01, 0x20, 0x00, 0x2b, 0xbb, 0xd1, 0x0d, 0x9b, 0x1f, 0x22, 0x18, 0x18, + 0x03, 0x00, 0x13, 0x40, 0x10, 0x42, 0x46, 0xd0, 0x01, 0x32, 0xd2, 0x1a, + 0x04, 0x2a, 0x3f, 0xdd, 0x1c, 0x22, 0xd3, 0x1a, 0x0a, 0x9a, 0xe4, 0x18, + 0xd2, 0x18, 0x0a, 0x92, 0x0d, 0x9a, 0xd3, 0x18, 0x0d, 0x93, 0x0a, 0x9b, + 0x00, 0x2b, 0x05, 0xdd, 0x1a, 0x00, 0x38, 0x00, 0x05, 0x99, 0x01, 0xf0, + 0xad, 0xfb, 0x05, 0x90, 0x0d, 0x9b, 0x00, 0x2b, 0x05, 0xdd, 0x31, 0x00, + 0x1a, 0x00, 0x38, 0x00, 0x01, 0xf0, 0xa4, 0xfb, 0x06, 0x00, 0x16, 0x9b, + 0x00, 0x2b, 0x26, 0xd0, 0x31, 0x00, 0x05, 0x98, 0x01, 0xf0, 0x0a, 0xfc, + 0x00, 0x28, 0x20, 0xda, 0x02, 0x9b, 0x0a, 0x22, 0x01, 0x3b, 0x02, 0x93, + 0x38, 0x00, 0x00, 0x23, 0x05, 0x99, 0x01, 0xf0, 0x97, 0xf9, 0x0f, 0x9b, + 0x05, 0x90, 0x00, 0x2b, 0x00, 0xd1, 0x66, 0xe1, 0x00, 0x23, 0x29, 0x00, + 0x0a, 0x22, 0x38, 0x00, 0x01, 0xf0, 0x8c, 0xf9, 0x0c, 0x9b, 0x05, 0x00, + 0x00, 0x2b, 0x47, 0xdc, 0x22, 0x9b, 0x02, 0x2b, 0x0d, 0xdc, 0x43, 0xe0, + 0x04, 0x2a, 0xc6, 0xd0, 0x13, 0x00, 0x1c, 0x33, 0xbc, 0xe7, 0x07, 0x9b, + 0x00, 0x2b, 0x35, 0xdc, 0x22, 0x9b, 0x02, 0x2b, 0x32, 0xdd, 0x07, 0x9b, + 0x0c, 0x93, 0x0c, 0x9b, 0x00, 0x2b, 0x0c, 0xd1, 0x31, 0x00, 0x05, 0x22, + 0x38, 0x00, 0x01, 0xf0, 0x6f, 0xf9, 0x06, 0x00, 0x01, 0x00, 0x05, 0x98, + 0x01, 0xf0, 0xd2, 0xfb, 0x00, 0x28, 0x00, 0xdd, 0xa5, 0xe5, 0x23, 0x9b, + 0xdb, 0x43, 0x02, 0x93, 0x06, 0x9b, 0x08, 0x93, 0x00, 0x24, 0x31, 0x00, + 0x38, 0x00, 0x01, 0xf0, 0x39, 0xf9, 0x00, 0x2d, 0x00, 0xd1, 0xb7, 0xe6, + 0x00, 0x2c, 0x05, 0xd0, 0xac, 0x42, 0x03, 0xd0, 0x21, 0x00, 0x38, 0x00, + 0x01, 0xf0, 0x2e, 0xf9, 0x29, 0x00, 0x38, 0x00, 0x01, 0xf0, 0x2a, 0xf9, + 0xaa, 0xe6, 0x00, 0x26, 0x35, 0x00, 0xe2, 0xe7, 0x02, 0x96, 0x14, 0x9e, + 0x35, 0x00, 0x84, 0xe5, 0x0f, 0x9b, 0x00, 0x2b, 0x00, 0xd1, 0xce, 0xe0, + 0x07, 0x9b, 0x0c, 0x93, 0x00, 0x2c, 0x05, 0xdd, 0x29, 0x00, 0x22, 0x00, + 0x38, 0x00, 0x01, 0xf0, 0x33, 0xfb, 0x05, 0x00, 0x0e, 0x9b, 0x28, 0x00, + 0x00, 0x2b, 0x22, 0xd0, 0x38, 0x00, 0x69, 0x68, 0x01, 0xf0, 0xc8, 0xf8, + 0x04, 0x1e, 0x0f, 0xd1, 0x02, 0x00, 0x05, 0x4b, 0x05, 0x49, 0xff, 0xf7, + 0x05, 0xfb, 0xc0, 0x46, 0x00, 0x00, 0x24, 0x40, 0x33, 0x04, 0x00, 0x00, + 0x00, 0x00, 0xf0, 0x7f, 0x7c, 0x03, 0x01, 0x10, 0xea, 0x02, 0x00, 0x00, + 0x29, 0x00, 0x2b, 0x69, 0x0c, 0x31, 0x9a, 0x1c, 0x92, 0x00, 0x0c, 0x30, + 0xfa, 0xf7, 0xc0, 0xfa, 0x01, 0x22, 0x21, 0x00, 0x38, 0x00, 0x01, 0xf0, + 0x0b, 0xfb, 0x06, 0x9b, 0x0c, 0x9a, 0x0a, 0x93, 0x01, 0x3b, 0x9b, 0x18, + 0x01, 0x22, 0x2c, 0x00, 0x05, 0x00, 0x14, 0x93, 0x08, 0x9b, 0x13, 0x40, + 0x0f, 0x93, 0x31, 0x00, 0x05, 0x98, 0xff, 0xf7, 0x3d, 0xfa, 0x03, 0x00, + 0x21, 0x00, 0x30, 0x33, 0x0d, 0x90, 0x05, 0x98, 0x07, 0x93, 0x01, 0xf0, + 0x61, 0xfb, 0x2a, 0x00, 0x0e, 0x90, 0x31, 0x00, 0x38, 0x00, 0x01, 0xf0, + 0x76, 0xfb, 0xc3, 0x68, 0x08, 0x90, 0x10, 0x93, 0x01, 0x23, 0x0c, 0x93, + 0x10, 0x9b, 0x00, 0x2b, 0x04, 0xd1, 0x01, 0x00, 0x05, 0x98, 0x01, 0xf0, + 0x4f, 0xfb, 0x0c, 0x90, 0x38, 0x00, 0x08, 0x99, 0x01, 0xf0, 0xbe, 0xf8, + 0x0a, 0x9b, 0x0c, 0x9a, 0x01, 0x33, 0x08, 0x93, 0x22, 0x9b, 0x13, 0x43, + 0x0f, 0x9a, 0x13, 0x43, 0x0c, 0xd1, 0x07, 0x9b, 0x39, 0x2b, 0x26, 0xd0, + 0x0e, 0x9b, 0x00, 0x2b, 0x02, 0xdd, 0x0d, 0x9b, 0x31, 0x33, 0x07, 0x93, + 0x0a, 0x9b, 0x07, 0x9a, 0x1a, 0x70, 0x6a, 0xe7, 0x0e, 0x9b, 0x00, 0x2b, + 0x04, 0xdb, 0x22, 0x9a, 0x13, 0x43, 0x0f, 0x9a, 0x13, 0x43, 0x1f, 0xd1, + 0x0c, 0x9b, 0x00, 0x2b, 0xf0, 0xdd, 0x05, 0x99, 0x01, 0x22, 0x38, 0x00, + 0x01, 0xf0, 0xb6, 0xfa, 0x31, 0x00, 0x05, 0x90, 0x01, 0xf0, 0x20, 0xfb, + 0x00, 0x28, 0x03, 0xdc, 0xe4, 0xd1, 0x07, 0x9b, 0xdb, 0x07, 0xe1, 0xd5, + 0x07, 0x9b, 0x39, 0x2b, 0xdb, 0xd1, 0x39, 0x23, 0x0a, 0x9a, 0x13, 0x70, + 0x08, 0x9b, 0x08, 0x93, 0x01, 0x3b, 0x1a, 0x78, 0x39, 0x2a, 0x68, 0xd0, + 0x01, 0x32, 0xd5, 0xe7, 0x0c, 0x9b, 0x00, 0x2b, 0x07, 0xdd, 0x07, 0x9b, + 0x39, 0x2b, 0xee, 0xd0, 0x07, 0x9b, 0x0a, 0x9a, 0x01, 0x33, 0x13, 0x70, + 0x37, 0xe7, 0x0a, 0x9b, 0x07, 0x9a, 0x1a, 0x70, 0x14, 0x9b, 0x0a, 0x9a, + 0x93, 0x42, 0x3e, 0xd0, 0x00, 0x23, 0x0a, 0x22, 0x05, 0x99, 0x38, 0x00, + 0x01, 0xf0, 0x8c, 0xf8, 0x00, 0x23, 0x05, 0x90, 0x0a, 0x22, 0x21, 0x00, + 0x38, 0x00, 0xac, 0x42, 0x06, 0xd1, 0x01, 0xf0, 0x83, 0xf8, 0x04, 0x00, + 0x05, 0x00, 0x08, 0x9b, 0x0a, 0x93, 0x78, 0xe7, 0x01, 0xf0, 0x7c, 0xf8, + 0x29, 0x00, 0x04, 0x00, 0x00, 0x23, 0x0a, 0x22, 0x38, 0x00, 0x01, 0xf0, + 0x75, 0xf8, 0x05, 0x00, 0xf1, 0xe7, 0x07, 0x9b, 0x0c, 0x93, 0x00, 0x24, + 0x31, 0x00, 0x05, 0x98, 0xff, 0xf7, 0xa8, 0xf9, 0x06, 0x9b, 0x30, 0x30, + 0x18, 0x55, 0x0c, 0x9b, 0x01, 0x34, 0x07, 0x90, 0xa3, 0x42, 0x07, 0xdd, + 0x00, 0x23, 0x0a, 0x22, 0x38, 0x00, 0x05, 0x99, 0x01, 0xf0, 0x5e, 0xf8, + 0x05, 0x90, 0xeb, 0xe7, 0x0c, 0x9b, 0x01, 0x20, 0x00, 0x2b, 0x00, 0xdd, + 0x18, 0x00, 0x00, 0x24, 0x06, 0x9b, 0x1b, 0x18, 0x08, 0x93, 0x05, 0x99, + 0x01, 0x22, 0x38, 0x00, 0x01, 0xf0, 0x48, 0xfa, 0x31, 0x00, 0x05, 0x90, + 0x01, 0xf0, 0xb2, 0xfa, 0x00, 0x28, 0x9b, 0xdc, 0x02, 0xd1, 0x07, 0x9b, + 0xdb, 0x07, 0x97, 0xd4, 0x08, 0x9b, 0x08, 0x93, 0x01, 0x3b, 0x1a, 0x78, + 0x30, 0x2a, 0xfa, 0xd0, 0xdb, 0xe6, 0x06, 0x9a, 0x9a, 0x42, 0x8e, 0xd1, + 0x02, 0x9b, 0x01, 0x33, 0x02, 0x93, 0x31, 0x23, 0x99, 0xe7, 0x09, 0x4b, + 0x26, 0x9a, 0x06, 0x93, 0x08, 0x4b, 0x00, 0x2a, 0x01, 0xd0, 0xff, 0xf7, + 0x3e, 0xfa, 0xff, 0xf7, 0x3e, 0xfa, 0x0c, 0x9b, 0x00, 0x2b, 0xb6, 0xdc, + 0x22, 0x9b, 0x02, 0x2b, 0x00, 0xdd, 0xac, 0xe6, 0xb1, 0xe7, 0xc0, 0x46, + 0x29, 0x03, 0x01, 0x10, 0x31, 0x03, 0x01, 0x10, 0x70, 0xb5, 0x05, 0x00, + 0x0c, 0x1e, 0x02, 0xd1, 0x00, 0x26, 0x30, 0x00, 0x70, 0xbd, 0x00, 0x28, + 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, 0x01, 0xd1, 0xfc, 0xf7, 0x1e, 0xfd, + 0x31, 0x4b, 0x9c, 0x42, 0x19, 0xd1, 0x6c, 0x68, 0xa3, 0x6e, 0xdb, 0x07, + 0x06, 0xd4, 0xa3, 0x89, 0x9b, 0x05, 0x03, 0xd4, 0x20, 0x00, 0x58, 0x30, + 0x02, 0xf0, 0x79, 0xfc, 0x0c, 0x22, 0xa3, 0x5e, 0x00, 0x2b, 0x14, 0xd1, + 0xa2, 0x6e, 0x01, 0x33, 0x16, 0x00, 0x1e, 0x40, 0x1a, 0x42, 0xdd, 0xd1, + 0x20, 0x00, 0x58, 0x30, 0x02, 0xf0, 0x6f, 0xfc, 0xd9, 0xe7, 0x24, 0x4b, + 0x9c, 0x42, 0x01, 0xd1, 0xac, 0x68, 0xe1, 0xe7, 0x22, 0x4b, 0x9c, 0x42, + 0xde, 0xd1, 0xec, 0x68, 0xdc, 0xe7, 0x21, 0x00, 0x28, 0x00, 0x00, 0xf0, + 0x47, 0xf8, 0x23, 0x6b, 0x06, 0x00, 0x00, 0x2b, 0x06, 0xd0, 0x28, 0x00, + 0x21, 0x6a, 0x98, 0x47, 0x00, 0x28, 0x01, 0xda, 0x01, 0x26, 0x76, 0x42, + 0xa3, 0x89, 0x1b, 0x06, 0x03, 0xd5, 0x28, 0x00, 0x21, 0x69, 0x00, 0xf0, + 0x71, 0xf9, 0x61, 0x6b, 0x00, 0x29, 0x08, 0xd0, 0x23, 0x00, 0x44, 0x33, + 0x99, 0x42, 0x02, 0xd0, 0x28, 0x00, 0x00, 0xf0, 0x67, 0xf9, 0x00, 0x23, + 0x63, 0x63, 0xa1, 0x6c, 0x00, 0x29, 0x04, 0xd0, 0x28, 0x00, 0x00, 0xf0, + 0x5f, 0xf9, 0x00, 0x23, 0xa3, 0x64, 0xfc, 0xf7, 0xab, 0xfc, 0x00, 0x23, + 0x25, 0x00, 0xa3, 0x81, 0xa3, 0x6e, 0x58, 0x35, 0xdb, 0x07, 0x02, 0xd4, + 0x28, 0x00, 0x02, 0xf0, 0x2e, 0xfc, 0x28, 0x00, 0x02, 0xf0, 0x26, 0xfc, + 0xfc, 0xf7, 0xa4, 0xfc, 0x93, 0xe7, 0xc0, 0x46, 0x78, 0x01, 0x01, 0x10, + 0x58, 0x01, 0x01, 0x10, 0x38, 0x01, 0x01, 0x10, 0x10, 0xb5, 0x04, 0x00, + 0xf7, 0xf7, 0x0e, 0xfb, 0x21, 0x00, 0xff, 0xf7, 0x81, 0xff, 0x10, 0xbd, + 0xf7, 0xb5, 0x0c, 0x23, 0xca, 0x5e, 0x0c, 0x00, 0x05, 0x00, 0x91, 0xb2, + 0x13, 0x07, 0x67, 0xd4, 0x80, 0x23, 0x1b, 0x01, 0x13, 0x43, 0x62, 0x68, + 0xa3, 0x81, 0x00, 0x2a, 0x04, 0xdc, 0x22, 0x6c, 0x00, 0x2a, 0x01, 0xdc, + 0x00, 0x20, 0xfe, 0xbd, 0xe7, 0x6a, 0x00, 0x2f, 0xfa, 0xd0, 0x00, 0x22, + 0x80, 0x21, 0x2e, 0x68, 0x2a, 0x60, 0x1a, 0x00, 0x49, 0x01, 0x0a, 0x40, + 0x0b, 0x42, 0x38, 0xd0, 0x60, 0x6d, 0xa3, 0x89, 0x5b, 0x07, 0x06, 0xd5, + 0x63, 0x68, 0xc0, 0x1a, 0x63, 0x6b, 0x00, 0x2b, 0x01, 0xd0, 0x23, 0x6c, + 0xc0, 0x1a, 0x02, 0x00, 0x21, 0x6a, 0x00, 0x23, 0x28, 0x00, 0xe7, 0x6a, + 0xb8, 0x47, 0xa1, 0x89, 0x43, 0x1c, 0x06, 0xd1, 0x2b, 0x68, 0x1d, 0x2b, + 0x35, 0xd8, 0x2e, 0x4a, 0xda, 0x40, 0xd3, 0x07, 0x31, 0xd5, 0x00, 0x22, + 0x2c, 0x4b, 0x62, 0x60, 0x0b, 0x40, 0x22, 0x69, 0x1b, 0xb2, 0xa3, 0x81, + 0x22, 0x60, 0xdb, 0x04, 0x05, 0xd5, 0x43, 0x1c, 0x02, 0xd1, 0x2b, 0x68, + 0x00, 0x2b, 0x00, 0xd1, 0x60, 0x65, 0x61, 0x6b, 0x2e, 0x60, 0x00, 0x29, + 0xc2, 0xd0, 0x23, 0x00, 0x44, 0x33, 0x99, 0x42, 0x02, 0xd0, 0x28, 0x00, + 0x00, 0xf0, 0xe6, 0xf8, 0x00, 0x20, 0x60, 0x63, 0xb9, 0xe7, 0x01, 0x23, + 0x28, 0x00, 0x21, 0x6a, 0xb8, 0x47, 0x43, 0x1c, 0xc1, 0xd1, 0x2b, 0x68, + 0x00, 0x2b, 0xbe, 0xd0, 0x1d, 0x2b, 0x01, 0xd0, 0x16, 0x2b, 0x01, 0xd1, + 0x2e, 0x60, 0xa9, 0xe7, 0x40, 0x23, 0xa2, 0x89, 0x13, 0x43, 0xa3, 0x81, + 0xa5, 0xe7, 0x40, 0x23, 0x0b, 0x43, 0xfa, 0xe7, 0x27, 0x69, 0x00, 0x2f, + 0x9e, 0xd0, 0x23, 0x68, 0x27, 0x60, 0xdb, 0x1b, 0x01, 0x93, 0x00, 0x23, + 0x8a, 0x07, 0x00, 0xd1, 0x63, 0x69, 0xa3, 0x60, 0x01, 0x9b, 0x00, 0x2b, + 0x00, 0xdc, 0x91, 0xe7, 0x3a, 0x00, 0x28, 0x00, 0x01, 0x9b, 0x21, 0x6a, + 0xa6, 0x6a, 0xb0, 0x47, 0x00, 0x28, 0x06, 0xdc, 0x40, 0x23, 0x01, 0x20, + 0xa2, 0x89, 0x40, 0x42, 0x13, 0x43, 0xa3, 0x81, 0x83, 0xe7, 0x01, 0x9b, + 0x3f, 0x18, 0x1b, 0x1a, 0x01, 0x93, 0xe7, 0xe7, 0x01, 0x00, 0x40, 0x20, + 0xff, 0xf7, 0xff, 0xff, 0x0b, 0x69, 0x70, 0xb5, 0x05, 0x00, 0x0c, 0x00, + 0x00, 0x2b, 0x02, 0xd1, 0x00, 0x25, 0x28, 0x00, 0x70, 0xbd, 0x00, 0x28, + 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, 0x01, 0xd1, 0xfc, 0xf7, 0x04, 0xfc, + 0x15, 0x4b, 0x9c, 0x42, 0x1d, 0xd1, 0x6c, 0x68, 0x0c, 0x22, 0xa3, 0x5e, + 0x00, 0x2b, 0xed, 0xd0, 0xa2, 0x6e, 0xd2, 0x07, 0x05, 0xd4, 0x9b, 0x05, + 0x03, 0xd4, 0x20, 0x00, 0x58, 0x30, 0x02, 0xf0, 0x5c, 0xfb, 0x28, 0x00, + 0x21, 0x00, 0xff, 0xf7, 0x43, 0xff, 0xa3, 0x6e, 0x05, 0x00, 0xdb, 0x07, + 0xdd, 0xd4, 0xa3, 0x89, 0x9b, 0x05, 0xda, 0xd4, 0x20, 0x00, 0x58, 0x30, + 0x02, 0xf0, 0x51, 0xfb, 0xd5, 0xe7, 0x06, 0x4b, 0x9c, 0x42, 0x01, 0xd1, + 0xac, 0x68, 0xdd, 0xe7, 0x04, 0x4b, 0x9c, 0x42, 0xda, 0xd1, 0xec, 0x68, + 0xd8, 0xe7, 0xc0, 0x46, 0x78, 0x01, 0x01, 0x10, 0x58, 0x01, 0x01, 0x10, + 0x38, 0x01, 0x01, 0x10, 0x10, 0xb5, 0x04, 0x1e, 0x05, 0xd1, 0x06, 0x4b, + 0x06, 0x49, 0x18, 0x68, 0xfc, 0xf7, 0x7f, 0xfc, 0x10, 0xbd, 0xf7, 0xf7, + 0x25, 0xfa, 0x21, 0x00, 0xff, 0xf7, 0xb0, 0xff, 0xf8, 0xe7, 0xc0, 0x46, + 0x98, 0x01, 0x01, 0x10, 0x9d, 0xd3, 0x00, 0x10, 0xf8, 0xb5, 0x0c, 0x00, + 0x06, 0x00, 0xfc, 0xf7, 0xaf, 0xfe, 0x20, 0x4f, 0xbb, 0x68, 0x5d, 0x68, + 0x03, 0x23, 0x9d, 0x43, 0x1e, 0x4b, 0x2c, 0x1b, 0xe4, 0x18, 0x24, 0x0b, + 0x01, 0x3c, 0x11, 0x33, 0x24, 0x03, 0x9c, 0x42, 0x04, 0xda, 0x30, 0x00, + 0xfc, 0xf7, 0xa6, 0xfe, 0x00, 0x20, 0xf8, 0xbd, 0x00, 0x21, 0x30, 0x00, + 0xfd, 0xf7, 0x4a, 0xfe, 0xbb, 0x68, 0x5b, 0x19, 0x98, 0x42, 0xf2, 0xd1, + 0x30, 0x00, 0x61, 0x42, 0xfd, 0xf7, 0x42, 0xfe, 0x43, 0x1c, 0x10, 0xd1, + 0x00, 0x21, 0x30, 0x00, 0xfd, 0xf7, 0x3c, 0xfe, 0xba, 0x68, 0x81, 0x1a, + 0x0f, 0x29, 0xe4, 0xdd, 0x0d, 0x4b, 0x1b, 0x68, 0xc0, 0x1a, 0x0d, 0x4b, + 0x18, 0x60, 0x01, 0x23, 0x0b, 0x43, 0x53, 0x60, 0xdb, 0xe7, 0xbb, 0x68, + 0x01, 0x27, 0x2d, 0x1b, 0x3d, 0x43, 0x5d, 0x60, 0x07, 0x4b, 0x30, 0x00, + 0x1a, 0x68, 0x14, 0x1b, 0x1c, 0x60, 0xfc, 0xf7, 0x79, 0xfe, 0x38, 0x00, + 0xd1, 0xe7, 0xc0, 0x46, 0x98, 0x06, 0x00, 0x20, 0xef, 0x0f, 0x00, 0x00, + 0x90, 0x06, 0x00, 0x20, 0xf0, 0x0d, 0x00, 0x20, 0xf7, 0xb5, 0x0d, 0x1e, + 0x01, 0x90, 0x2d, 0xd0, 0xfc, 0xf7, 0x60, 0xfe, 0x01, 0x23, 0x29, 0x00, + 0x9c, 0x46, 0x08, 0x39, 0x4f, 0x68, 0x62, 0x46, 0x3b, 0x00, 0x66, 0x46, + 0x93, 0x43, 0xc8, 0x18, 0x45, 0x68, 0x02, 0x32, 0x95, 0x43, 0x4a, 0x4a, + 0x37, 0x40, 0x96, 0x68, 0x86, 0x42, 0x1a, 0xd1, 0x5b, 0x19, 0x00, 0x2f, + 0x06, 0xd1, 0x08, 0x68, 0x09, 0x1a, 0x8d, 0x68, 0x1b, 0x18, 0xc8, 0x68, + 0xe8, 0x60, 0x85, 0x60, 0x01, 0x20, 0x18, 0x43, 0x48, 0x60, 0x91, 0x60, + 0x41, 0x4a, 0x12, 0x68, 0x9a, 0x42, 0x04, 0xd8, 0x40, 0x4b, 0x01, 0x98, + 0x19, 0x68, 0xff, 0xf7, 0x83, 0xff, 0x01, 0x98, 0xfc, 0xf7, 0x3c, 0xfe, + 0xf7, 0xbd, 0x00, 0x26, 0x45, 0x60, 0xb7, 0x42, 0x09, 0xd1, 0x0f, 0x68, + 0x3a, 0x4c, 0xc9, 0x1b, 0xdb, 0x19, 0x8f, 0x68, 0xa7, 0x42, 0x2c, 0xd0, + 0xcc, 0x68, 0xfc, 0x60, 0xa7, 0x60, 0x47, 0x19, 0x7c, 0x68, 0x01, 0x27, + 0x3c, 0x42, 0x0b, 0xd1, 0x5b, 0x19, 0x85, 0x68, 0x00, 0x2e, 0x22, 0xd1, + 0x31, 0x4c, 0xa5, 0x42, 0x1f, 0xd1, 0x3e, 0x00, 0x51, 0x61, 0x11, 0x61, + 0xcd, 0x60, 0x8d, 0x60, 0x01, 0x25, 0x28, 0x00, 0x18, 0x43, 0x48, 0x60, + 0xcb, 0x50, 0x00, 0x2e, 0xd5, 0xd1, 0x80, 0x20, 0x80, 0x00, 0x83, 0x42, + 0x13, 0xd2, 0xd8, 0x08, 0x5b, 0x09, 0x9d, 0x40, 0x53, 0x68, 0xc0, 0x00, + 0x1d, 0x43, 0x55, 0x60, 0x82, 0x18, 0x93, 0x68, 0xca, 0x60, 0x8b, 0x60, + 0x91, 0x60, 0xd9, 0x60, 0xc3, 0xe7, 0x66, 0x46, 0xd3, 0xe7, 0xc0, 0x68, + 0xe8, 0x60, 0x85, 0x60, 0xe0, 0xe7, 0x5d, 0x0a, 0x04, 0x2d, 0x12, 0xd8, + 0x98, 0x09, 0x38, 0x30, 0xc6, 0x00, 0xb6, 0x18, 0xb5, 0x68, 0x03, 0x27, + 0xae, 0x42, 0x25, 0xd1, 0x01, 0x23, 0x80, 0x10, 0x83, 0x40, 0x50, 0x68, + 0x03, 0x43, 0x53, 0x60, 0xce, 0x60, 0x8d, 0x60, 0xb1, 0x60, 0xe9, 0x60, + 0xa7, 0xe7, 0x14, 0x2d, 0x02, 0xd8, 0x28, 0x00, 0x5b, 0x30, 0xe9, 0xe7, + 0x54, 0x2d, 0x02, 0xd8, 0x18, 0x0b, 0x6e, 0x30, 0xe4, 0xe7, 0xaa, 0x20, + 0x40, 0x00, 0x85, 0x42, 0x02, 0xd8, 0xd8, 0x0b, 0x77, 0x30, 0xdd, 0xe7, + 0x0b, 0x4e, 0x7e, 0x20, 0xb5, 0x42, 0xd9, 0xd8, 0x98, 0x0c, 0x7c, 0x30, + 0xd6, 0xe7, 0xad, 0x68, 0xae, 0x42, 0x03, 0xd0, 0x6a, 0x68, 0xba, 0x43, + 0x9a, 0x42, 0xf8, 0xd8, 0xee, 0x68, 0xd9, 0xe7, 0x98, 0x06, 0x00, 0x20, + 0x94, 0x06, 0x00, 0x20, 0xec, 0x0d, 0x00, 0x20, 0xa0, 0x06, 0x00, 0x20, + 0x54, 0x05, 0x00, 0x00, 0xf0, 0xb5, 0x93, 0x68, 0x87, 0xb0, 0x0c, 0x00, + 0x17, 0x00, 0x03, 0x90, 0x00, 0x2b, 0x02, 0xd1, 0x00, 0x20, 0x07, 0xb0, + 0xf0, 0xbd, 0x8b, 0x89, 0x1b, 0x07, 0x59, 0xd5, 0x0b, 0x69, 0x00, 0x2b, + 0x56, 0xd0, 0x3b, 0x68, 0x02, 0x22, 0x02, 0x93, 0xa3, 0x89, 0x18, 0x00, + 0x10, 0x40, 0x13, 0x42, 0x75, 0xd1, 0x01, 0x22, 0x01, 0x21, 0x1a, 0x40, + 0x0b, 0x42, 0x00, 0xd1, 0xad, 0xe0, 0x06, 0x00, 0x01, 0x90, 0x04, 0x90, + 0x04, 0x9b, 0x00, 0x2b, 0x00, 0xd1, 0x16, 0xe1, 0x00, 0x28, 0x0c, 0xd1, + 0x1a, 0x00, 0x0a, 0x21, 0x30, 0x00, 0x02, 0xf0, 0xd3, 0xfa, 0x04, 0x9b, + 0x01, 0x33, 0x01, 0x93, 0x00, 0x28, 0x02, 0xd0, 0x01, 0x30, 0x83, 0x1b, + 0x01, 0x93, 0x01, 0x9b, 0x04, 0x9a, 0x05, 0x93, 0x93, 0x42, 0x00, 0xd9, + 0x05, 0x92, 0x20, 0x68, 0x22, 0x69, 0x63, 0x69, 0x90, 0x42, 0x00, 0xd8, + 0x04, 0xe1, 0xa2, 0x68, 0x9d, 0x18, 0x05, 0x9a, 0xaa, 0x42, 0x00, 0xdc, + 0xfe, 0xe0, 0x31, 0x00, 0x2a, 0x00, 0x02, 0xf0, 0x05, 0xfb, 0x23, 0x68, + 0x21, 0x00, 0x5b, 0x19, 0x03, 0x98, 0x23, 0x60, 0xff, 0xf7, 0x58, 0xfe, + 0x00, 0x28, 0x73, 0xd1, 0x01, 0x9b, 0x01, 0x20, 0x5b, 0x1b, 0x01, 0x93, + 0x05, 0xd1, 0x21, 0x00, 0x03, 0x98, 0xff, 0xf7, 0x4d, 0xfe, 0x00, 0x28, + 0x68, 0xd1, 0x04, 0x9b, 0x76, 0x19, 0x5b, 0x1b, 0x04, 0x93, 0xbb, 0x68, + 0x5d, 0x1b, 0xbd, 0x60, 0xba, 0xd1, 0x9f, 0xe7, 0x21, 0x00, 0x03, 0x98, + 0x01, 0xf0, 0xf0, 0xff, 0x00, 0x28, 0xa2, 0xd0, 0x01, 0x20, 0x40, 0x42, + 0x97, 0xe7, 0x02, 0x9b, 0x1b, 0x68, 0x01, 0x93, 0x02, 0x9b, 0x5d, 0x68, + 0x08, 0x33, 0x02, 0x93, 0x00, 0x2d, 0xf6, 0xd0, 0x72, 0x4a, 0x2b, 0x00, + 0x95, 0x42, 0x00, 0xd9, 0x13, 0x00, 0x01, 0x9a, 0x21, 0x6a, 0x03, 0x98, + 0xa6, 0x6a, 0xb0, 0x47, 0x00, 0x28, 0x41, 0xdd, 0x01, 0x9b, 0x2d, 0x1a, + 0x1b, 0x18, 0x01, 0x93, 0xbb, 0x68, 0x18, 0x1a, 0xb8, 0x60, 0xe9, 0xd1, + 0x78, 0xe7, 0x00, 0x23, 0x1d, 0x00, 0x01, 0x93, 0xe4, 0xe7, 0x02, 0x9b, + 0x1b, 0x68, 0x04, 0x93, 0x02, 0x9b, 0x5b, 0x68, 0x01, 0x93, 0x02, 0x9b, + 0x08, 0x33, 0x02, 0x93, 0x01, 0x9b, 0x00, 0x2b, 0xf3, 0xd0, 0x80, 0x23, + 0xa2, 0x89, 0x9b, 0x00, 0x20, 0x68, 0xa5, 0x68, 0x1a, 0x42, 0x64, 0xd0, + 0x01, 0x9b, 0x9d, 0x42, 0x38, 0xd8, 0x90, 0x23, 0xdb, 0x00, 0x1a, 0x42, + 0x34, 0xd0, 0x21, 0x69, 0x43, 0x1a, 0x03, 0x20, 0x05, 0x93, 0x63, 0x69, + 0x58, 0x43, 0x05, 0x9b, 0xc6, 0x0f, 0x36, 0x18, 0x01, 0x98, 0x01, 0x33, + 0x1b, 0x18, 0x76, 0x10, 0xb3, 0x42, 0x00, 0xd9, 0x1e, 0x00, 0x53, 0x05, + 0x3c, 0xd5, 0x31, 0x00, 0x03, 0x98, 0xfc, 0xf7, 0xe1, 0xfa, 0x05, 0x1e, + 0x0a, 0xd1, 0x0c, 0x23, 0x03, 0x9a, 0x13, 0x60, 0x40, 0x23, 0xa2, 0x89, + 0x13, 0x43, 0xa3, 0x81, 0xa0, 0xe7, 0x04, 0x92, 0x01, 0x92, 0xcb, 0xe7, + 0x05, 0x9a, 0x21, 0x69, 0xf9, 0xf7, 0x86, 0xfe, 0xa3, 0x89, 0x46, 0x4a, + 0x1a, 0x40, 0x80, 0x23, 0x13, 0x43, 0xa3, 0x81, 0x05, 0x9b, 0x25, 0x61, + 0xed, 0x18, 0x25, 0x60, 0x66, 0x61, 0x01, 0x9d, 0xf6, 0x1a, 0xa6, 0x60, + 0x01, 0x9e, 0xb5, 0x42, 0x00, 0xd9, 0x35, 0x00, 0x2a, 0x00, 0x04, 0x99, + 0x20, 0x68, 0x02, 0xf0, 0x65, 0xfa, 0xa3, 0x68, 0x5b, 0x1b, 0xa3, 0x60, + 0x23, 0x68, 0x5d, 0x19, 0x25, 0x60, 0x04, 0x9b, 0x9b, 0x19, 0x04, 0x93, + 0x01, 0x9b, 0x9b, 0x1b, 0x01, 0x93, 0xbb, 0x68, 0x9e, 0x1b, 0xbe, 0x60, + 0xa0, 0xd1, 0x0b, 0xe7, 0x32, 0x00, 0x03, 0x98, 0x01, 0xf0, 0x12, 0xfd, + 0x05, 0x1e, 0xd7, 0xd1, 0x21, 0x69, 0x03, 0x98, 0xff, 0xf7, 0x48, 0xfe, + 0x80, 0x22, 0xa3, 0x89, 0x93, 0x43, 0xa3, 0x81, 0xb9, 0xe7, 0x23, 0x69, + 0x83, 0x42, 0x03, 0xd3, 0x66, 0x69, 0x01, 0x9b, 0x9e, 0x42, 0x17, 0xd9, + 0x01, 0x9b, 0x9d, 0x42, 0x00, 0xd9, 0x1d, 0x00, 0x2a, 0x00, 0x04, 0x99, + 0x02, 0xf0, 0x36, 0xfa, 0xa3, 0x68, 0x22, 0x68, 0x5b, 0x1b, 0x52, 0x19, + 0x2e, 0x00, 0xa3, 0x60, 0x22, 0x60, 0x00, 0x2b, 0xcd, 0xd1, 0x21, 0x00, + 0x03, 0x98, 0xff, 0xf7, 0x83, 0xfd, 0x00, 0x28, 0xc7, 0xd0, 0x9d, 0xe7, + 0x01, 0x9a, 0x1c, 0x4b, 0x10, 0x00, 0x9a, 0x42, 0x00, 0xd9, 0x1b, 0x48, + 0x31, 0x00, 0xf8, 0xf7, 0x01, 0xff, 0x33, 0x00, 0x04, 0x9a, 0x43, 0x43, + 0x21, 0x6a, 0x03, 0x98, 0xa5, 0x6a, 0xa8, 0x47, 0x06, 0x1e, 0xb4, 0xdc, + 0x8a, 0xe7, 0x02, 0x9b, 0x00, 0x20, 0x1e, 0x68, 0x5b, 0x68, 0x04, 0x93, + 0x02, 0x9b, 0x08, 0x33, 0x02, 0x93, 0xdb, 0xe6, 0x05, 0x9a, 0x93, 0x42, + 0x08, 0xdc, 0xa5, 0x6a, 0x32, 0x00, 0x21, 0x6a, 0x03, 0x98, 0xa8, 0x47, + 0x05, 0x1e, 0x00, 0xdd, 0x02, 0xe7, 0x75, 0xe7, 0x05, 0x9a, 0x31, 0x00, + 0x02, 0xf0, 0xfa, 0xf9, 0x05, 0x9a, 0xa3, 0x68, 0x15, 0x00, 0x9b, 0x1a, + 0xa3, 0x60, 0x23, 0x68, 0x9b, 0x18, 0x23, 0x60, 0xf4, 0xe6, 0xc0, 0x46, + 0x00, 0xfc, 0xff, 0x7f, 0x7f, 0xfb, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x7f, + 0xff, 0xff, 0xff, 0x7f, 0x02, 0x00, 0xf0, 0xb5, 0x04, 0x69, 0x14, 0x32, + 0x13, 0x00, 0x85, 0xb0, 0x4f, 0x11, 0xbc, 0x42, 0x31, 0xdd, 0xbb, 0x00, + 0xd3, 0x18, 0x1f, 0x26, 0x01, 0x93, 0x0b, 0x00, 0xa5, 0x00, 0x33, 0x40, + 0x55, 0x19, 0x02, 0x93, 0x31, 0x42, 0x0c, 0xd1, 0x16, 0x00, 0x01, 0x99, + 0x8d, 0x42, 0x38, 0xd8, 0x01, 0x99, 0x00, 0x23, 0x03, 0x39, 0x8d, 0x42, + 0x01, 0xd3, 0xe3, 0x1b, 0x9b, 0x00, 0xd3, 0x18, 0x19, 0xe0, 0x20, 0x21, + 0x02, 0x9b, 0x01, 0x9e, 0xcb, 0x1a, 0x03, 0x93, 0x02, 0xce, 0x02, 0x9b, + 0x94, 0x46, 0xd9, 0x40, 0x00, 0x91, 0xb5, 0x42, 0x16, 0xd8, 0x01, 0x9e, + 0x00, 0x23, 0x01, 0x36, 0xb5, 0x42, 0x02, 0xd3, 0xe3, 0x1b, 0x9b, 0x00, + 0x04, 0x3b, 0x00, 0x99, 0xd3, 0x18, 0x19, 0x60, 0x00, 0x29, 0x00, 0xd0, + 0x04, 0x33, 0x99, 0x1a, 0x89, 0x10, 0x01, 0x61, 0x93, 0x42, 0x01, 0xd1, + 0x00, 0x23, 0x43, 0x61, 0x05, 0xb0, 0xf0, 0xbd, 0x33, 0x68, 0x03, 0x99, + 0x8b, 0x40, 0x00, 0x99, 0x19, 0x43, 0x63, 0x46, 0x02, 0xc3, 0x9c, 0x46, + 0x02, 0xce, 0x02, 0x9b, 0xd9, 0x40, 0x00, 0x91, 0xd9, 0xe7, 0x08, 0xc9, + 0x08, 0xc6, 0xc1, 0xe7, 0x02, 0x00, 0x30, 0x3a, 0x03, 0x00, 0x09, 0x2a, + 0x02, 0xd8, 0x20, 0x3b, 0xd8, 0xb2, 0x70, 0x47, 0x02, 0x00, 0x61, 0x3a, + 0x05, 0x2a, 0x01, 0xd8, 0x47, 0x3b, 0xf7, 0xe7, 0x1a, 0x00, 0x41, 0x3a, + 0x00, 0x20, 0x05, 0x2a, 0xf3, 0xd8, 0x27, 0x3b, 0xf0, 0xe7, 0xf0, 0xb5, + 0x8d, 0xb0, 0x0a, 0x93, 0xbf, 0x4b, 0x05, 0x90, 0x1b, 0x68, 0x09, 0x91, + 0x18, 0x00, 0x02, 0x92, 0x07, 0x93, 0xfd, 0xf7, 0xdb, 0xfc, 0x02, 0x22, + 0x07, 0x9b, 0x52, 0x42, 0x1b, 0x18, 0x01, 0x3b, 0x1b, 0x78, 0x03, 0x90, + 0x0b, 0x93, 0x09, 0x9b, 0x19, 0x68, 0x8b, 0x1c, 0x52, 0x1a, 0xd1, 0x18, + 0x01, 0x93, 0x08, 0x91, 0x01, 0x99, 0x01, 0x33, 0x08, 0x78, 0x30, 0x28, + 0xf7, 0xd0, 0xff, 0xf7, 0xc9, 0xff, 0x00, 0x23, 0x1c, 0x00, 0x04, 0x93, + 0x98, 0x42, 0x1f, 0xd1, 0x03, 0x9a, 0x07, 0x99, 0x01, 0x98, 0x01, 0xf0, + 0xc7, 0xfd, 0x07, 0x00, 0xa0, 0x42, 0x00, 0xd0, 0x6b, 0xe0, 0x01, 0x9b, + 0x03, 0x9a, 0x98, 0x5c, 0x9d, 0x18, 0xff, 0xf7, 0xb5, 0xff, 0x01, 0x23, + 0x04, 0x93, 0xa0, 0x42, 0x30, 0xd0, 0x01, 0x95, 0x01, 0x9b, 0x18, 0x78, + 0x30, 0x28, 0x09, 0xd0, 0xff, 0xf7, 0xaa, 0xff, 0x42, 0x42, 0x42, 0x41, + 0x01, 0x23, 0x2c, 0x00, 0x04, 0x92, 0x08, 0x93, 0x01, 0x9d, 0x04, 0xe0, + 0x01, 0x9b, 0x01, 0x33, 0x01, 0x93, 0xed, 0xe7, 0x01, 0x35, 0x28, 0x78, + 0xff, 0xf7, 0x9a, 0xff, 0x07, 0x1e, 0xf9, 0xd1, 0x28, 0x00, 0x03, 0x9a, + 0x07, 0x99, 0x01, 0xf0, 0x9b, 0xfd, 0x00, 0x28, 0x0e, 0xd1, 0x00, 0x2c, + 0x07, 0xd1, 0x03, 0x9b, 0xed, 0x18, 0x2c, 0x00, 0x28, 0x78, 0xff, 0xf7, + 0x89, 0xff, 0x00, 0x28, 0x02, 0xd1, 0x64, 0x1b, 0xa7, 0x00, 0x03, 0xe0, + 0x01, 0x35, 0xf5, 0xe7, 0x00, 0x2c, 0xf8, 0xd1, 0x20, 0x22, 0x2b, 0x78, + 0x2e, 0x00, 0x93, 0x43, 0x50, 0x2b, 0x1d, 0xd1, 0x6b, 0x78, 0x2b, 0x2b, + 0x2c, 0xd0, 0x2d, 0x2b, 0x2e, 0xd0, 0x00, 0x23, 0x6e, 0x1c, 0x06, 0x93, + 0x30, 0x78, 0xff, 0xf7, 0x6f, 0xff, 0x43, 0x1e, 0xdb, 0xb2, 0x18, 0x2b, + 0x2b, 0xd8, 0x10, 0x38, 0x04, 0x00, 0x70, 0x78, 0xff, 0xf7, 0x66, 0xff, + 0x43, 0x1e, 0xdb, 0xb2, 0x01, 0x36, 0x18, 0x2b, 0x1c, 0xd9, 0x06, 0x9b, + 0x00, 0x2b, 0x00, 0xd0, 0x64, 0x42, 0x3f, 0x19, 0x09, 0x9b, 0x1e, 0x60, + 0x04, 0x9b, 0x00, 0x2b, 0x19, 0xd0, 0x00, 0x26, 0x08, 0x9b, 0xb3, 0x42, + 0x00, 0xd1, 0x06, 0x36, 0x30, 0x00, 0x0d, 0xb0, 0xf0, 0xbd, 0x01, 0x23, + 0x00, 0x27, 0x01, 0x9d, 0x04, 0x93, 0xc9, 0xe7, 0x00, 0x23, 0x06, 0x93, + 0xae, 0x1c, 0xd3, 0xe7, 0x01, 0x23, 0xfa, 0xe7, 0x0a, 0x23, 0x5c, 0x43, + 0x24, 0x18, 0x10, 0x3c, 0xd5, 0xe7, 0x2e, 0x00, 0xe0, 0xe7, 0x01, 0x9b, + 0x04, 0x99, 0xeb, 0x1a, 0x01, 0x3b, 0x07, 0x2b, 0x0a, 0xdc, 0x05, 0x98, + 0x00, 0xf0, 0xc0, 0xfa, 0x04, 0x1e, 0x08, 0xd1, 0x02, 0x00, 0xde, 0x21, + 0x64, 0x4b, 0x65, 0x48, 0xf8, 0xf7, 0x70, 0xfd, 0x01, 0x31, 0x5b, 0x10, + 0xef, 0xe7, 0x03, 0x00, 0x14, 0x33, 0x04, 0x93, 0x09, 0x93, 0x00, 0x23, + 0x1e, 0x00, 0x06, 0x93, 0x01, 0x9b, 0xab, 0x42, 0x40, 0xd3, 0x09, 0x9d, + 0x04, 0x9b, 0x40, 0xc5, 0xed, 0x1a, 0xad, 0x10, 0x30, 0x00, 0x25, 0x61, + 0x00, 0xf0, 0x9a, 0xfb, 0x02, 0x9b, 0x6d, 0x01, 0x1b, 0x68, 0x2e, 0x1a, + 0x01, 0x93, 0x9e, 0x42, 0x5a, 0xdd, 0xf6, 0x1a, 0x31, 0x00, 0x20, 0x00, + 0x00, 0xf0, 0x55, 0xff, 0x05, 0x1e, 0x16, 0xd0, 0x01, 0x25, 0x1f, 0x21, + 0x28, 0x00, 0x73, 0x1e, 0x19, 0x40, 0x88, 0x40, 0x01, 0x00, 0x5a, 0x11, + 0x04, 0x98, 0x92, 0x00, 0x12, 0x58, 0x0a, 0x42, 0x09, 0xd0, 0xab, 0x42, + 0x06, 0xdd, 0x20, 0x00, 0xb1, 0x1e, 0x00, 0xf0, 0x40, 0xff, 0x02, 0x35, + 0x00, 0x28, 0x00, 0xd1, 0x02, 0x25, 0x31, 0x00, 0x20, 0x00, 0xff, 0xf7, + 0x99, 0xfe, 0xbf, 0x19, 0x02, 0x9b, 0x9b, 0x68, 0x03, 0x93, 0xbb, 0x42, + 0x42, 0xda, 0x21, 0x00, 0x05, 0x98, 0x00, 0xf0, 0xb3, 0xfa, 0x00, 0x23, + 0x12, 0x9a, 0xa3, 0x26, 0x13, 0x60, 0x8b, 0xe7, 0x6b, 0x1e, 0x08, 0x93, + 0x0b, 0x9a, 0x1b, 0x78, 0x93, 0x42, 0x14, 0xd0, 0x06, 0x9b, 0x20, 0x2b, + 0x04, 0xd1, 0x09, 0x9b, 0x40, 0xc3, 0x00, 0x26, 0x09, 0x93, 0x06, 0x96, + 0x08, 0x9b, 0x18, 0x78, 0xff, 0xf7, 0xcc, 0xfe, 0x0f, 0x23, 0x18, 0x40, + 0x06, 0x9b, 0x08, 0x9d, 0x98, 0x40, 0x04, 0x33, 0x06, 0x43, 0x06, 0x93, + 0xa0, 0xe7, 0x01, 0x23, 0x03, 0x9a, 0x9d, 0x1a, 0x08, 0x9b, 0x5d, 0x19, + 0x01, 0x9b, 0x9d, 0x42, 0xe2, 0xd3, 0x28, 0x00, 0x07, 0x99, 0x01, 0xf0, + 0xbf, 0xfc, 0x00, 0x28, 0xdc, 0xd1, 0x91, 0xe7, 0x01, 0x9b, 0x00, 0x25, + 0x9e, 0x42, 0xc3, 0xda, 0x9e, 0x1b, 0x21, 0x00, 0x32, 0x00, 0x05, 0x98, + 0x00, 0xf0, 0x98, 0xfc, 0x03, 0x00, 0x14, 0x33, 0x04, 0x00, 0xbf, 0x1b, + 0x04, 0x93, 0xb7, 0xe7, 0x02, 0x9b, 0x5e, 0x68, 0xbe, 0x42, 0x72, 0xdd, + 0x01, 0x9b, 0xf6, 0x1b, 0xb3, 0x42, 0x39, 0xdc, 0x02, 0x9b, 0xdb, 0x68, + 0x02, 0x2b, 0x26, 0xd0, 0x03, 0x2b, 0x28, 0xd0, 0x01, 0x2b, 0x19, 0xd1, + 0x01, 0x9b, 0xb3, 0x42, 0x16, 0xd1, 0x01, 0x2b, 0x0d, 0xd1, 0x02, 0x9b, + 0x62, 0x26, 0x5b, 0x68, 0x01, 0x93, 0x01, 0x9a, 0x0a, 0x9b, 0x1a, 0x60, + 0x01, 0x23, 0x04, 0x9a, 0x23, 0x61, 0x13, 0x60, 0x12, 0x9b, 0x1c, 0x60, + 0x2e, 0xe7, 0x01, 0x99, 0x20, 0x00, 0x01, 0x39, 0x00, 0xf0, 0xc7, 0xfe, + 0x00, 0x28, 0xea, 0xd1, 0x21, 0x00, 0x05, 0x98, 0x00, 0xf0, 0x46, 0xfa, + 0x00, 0x23, 0x12, 0x9a, 0x50, 0x26, 0x13, 0x60, 0x1e, 0xe7, 0x13, 0x9b, + 0x00, 0x2b, 0xf3, 0xd1, 0xdd, 0xe7, 0x13, 0x9b, 0x00, 0x2b, 0xda, 0xd1, + 0xee, 0xe7, 0xc0, 0x46, 0xc8, 0x03, 0x01, 0x10, 0x7c, 0x03, 0x01, 0x10, + 0x8d, 0x03, 0x01, 0x10, 0x77, 0x1e, 0x00, 0x2d, 0x2f, 0xd1, 0x00, 0x2f, + 0x04, 0xd0, 0x39, 0x00, 0x20, 0x00, 0x00, 0xf0, 0xa4, 0xfe, 0x05, 0x00, + 0x1f, 0x23, 0x7a, 0x11, 0x1f, 0x40, 0x1e, 0x3b, 0xbb, 0x40, 0x04, 0x99, + 0x92, 0x00, 0x52, 0x58, 0x1a, 0x42, 0x01, 0xd0, 0x02, 0x23, 0x1d, 0x43, + 0x01, 0x9b, 0x31, 0x00, 0x9b, 0x1b, 0x02, 0x26, 0x20, 0x00, 0x01, 0x93, + 0xff, 0xf7, 0xf0, 0xfd, 0x02, 0x9b, 0x5f, 0x68, 0x00, 0x2d, 0x41, 0xd0, + 0x02, 0x9b, 0xdb, 0x68, 0x02, 0x2b, 0x10, 0xd0, 0x03, 0x2b, 0x12, 0xd0, + 0x01, 0x2b, 0x06, 0xd1, 0xaa, 0x07, 0x04, 0xd5, 0x04, 0x9a, 0x10, 0x68, + 0x05, 0x43, 0x1d, 0x42, 0x0c, 0xd1, 0x10, 0x23, 0x2f, 0xe0, 0x01, 0x25, + 0xd4, 0xe7, 0x01, 0x26, 0xe8, 0xe7, 0x01, 0x23, 0x13, 0x9a, 0x9b, 0x1a, + 0x13, 0x93, 0x13, 0x9b, 0x00, 0x2b, 0xf2, 0xd0, 0x23, 0x69, 0x00, 0x20, + 0x03, 0x93, 0x9b, 0x00, 0x04, 0x93, 0x23, 0x00, 0x04, 0x9a, 0x14, 0x33, + 0x99, 0x18, 0x1a, 0x68, 0x55, 0x1c, 0x1e, 0xd0, 0x01, 0x32, 0x1a, 0x60, + 0x23, 0x00, 0x14, 0x33, 0x02, 0x2e, 0x40, 0xd1, 0x02, 0x9a, 0x01, 0x99, + 0x12, 0x68, 0x01, 0x3a, 0x8a, 0x42, 0x0b, 0xd1, 0x4a, 0x11, 0x1f, 0x21, + 0x01, 0x98, 0x92, 0x00, 0x01, 0x40, 0x01, 0x20, 0x05, 0x00, 0x8d, 0x40, + 0xd3, 0x58, 0x2b, 0x42, 0x00, 0xd0, 0x01, 0x26, 0x20, 0x23, 0x1e, 0x43, + 0x12, 0x9b, 0x1c, 0x60, 0x0a, 0x9b, 0x1f, 0x60, 0xa6, 0xe6, 0x01, 0xc3, + 0x99, 0x42, 0xda, 0xd8, 0x03, 0x9b, 0xa2, 0x68, 0x93, 0x42, 0x17, 0xdb, + 0x63, 0x68, 0x05, 0x98, 0x59, 0x1c, 0x00, 0xf0, 0x79, 0xf9, 0x05, 0x1e, + 0x03, 0xd1, 0x02, 0x00, 0x84, 0x21, 0x1c, 0x4b, 0xb7, 0xe6, 0x21, 0x00, + 0x23, 0x69, 0x0c, 0x31, 0x9a, 0x1c, 0x92, 0x00, 0x0c, 0x30, 0xf9, 0xf7, + 0x7d, 0xfb, 0x21, 0x00, 0x05, 0x98, 0x00, 0xf0, 0xab, 0xf9, 0x2c, 0x00, + 0x23, 0x69, 0x5a, 0x1c, 0x22, 0x61, 0x01, 0x22, 0x04, 0x33, 0x9b, 0x00, + 0xe3, 0x18, 0x5a, 0x60, 0xba, 0xe7, 0x22, 0x69, 0x03, 0x99, 0x8a, 0x42, + 0x09, 0xdd, 0x01, 0x21, 0x20, 0x00, 0xff, 0xf7, 0x75, 0xfd, 0x02, 0x9b, + 0x01, 0x37, 0x9b, 0x68, 0xbb, 0x42, 0xc2, 0xda, 0xdb, 0xe6, 0x1f, 0x22, + 0x01, 0x9d, 0x01, 0x99, 0x01, 0x26, 0x15, 0x40, 0x11, 0x42, 0xbb, 0xd0, + 0x04, 0x9a, 0x9b, 0x18, 0x04, 0x3b, 0x18, 0x68, 0x00, 0xf0, 0x3a, 0xfa, + 0x20, 0x23, 0x5d, 0x1b, 0xa8, 0x42, 0xe4, 0xdb, 0xb0, 0xe7, 0xc0, 0x46, + 0x7c, 0x03, 0x01, 0x10, 0x08, 0x23, 0x70, 0xb5, 0x20, 0x25, 0x9a, 0x1a, + 0x92, 0x00, 0xad, 0x1a, 0x43, 0x68, 0x06, 0x68, 0x1c, 0x00, 0xac, 0x40, + 0xd3, 0x40, 0x34, 0x43, 0x04, 0x60, 0x43, 0x60, 0x04, 0x30, 0x88, 0x42, + 0xf4, 0xd3, 0x70, 0xbd, 0x30, 0xb5, 0x03, 0x68, 0x0c, 0x78, 0x01, 0x33, + 0x00, 0x2c, 0x02, 0xd1, 0x03, 0x60, 0x01, 0x20, 0x30, 0xbd, 0x1a, 0x78, + 0x15, 0x00, 0x41, 0x3d, 0x19, 0x2d, 0x00, 0xd8, 0x20, 0x32, 0x01, 0x31, + 0xa2, 0x42, 0xef, 0xd0, 0x00, 0x20, 0xf3, 0xe7, 0xf0, 0xb5, 0x0b, 0x68, + 0x8b, 0xb0, 0x01, 0x92, 0x01, 0x99, 0x5a, 0x11, 0x92, 0x00, 0x8a, 0x18, + 0x02, 0x92, 0x19, 0x00, 0x1f, 0x22, 0x11, 0x40, 0x08, 0x90, 0x06, 0x91, + 0x13, 0x42, 0x02, 0xd0, 0x02, 0x9b, 0x04, 0x33, 0x02, 0x93, 0x02, 0x9b, + 0x00, 0x25, 0x1e, 0x1f, 0x37, 0x00, 0x34, 0x00, 0x08, 0x9b, 0x35, 0x60, + 0x1b, 0x68, 0x07, 0x95, 0x05, 0x93, 0x03, 0x95, 0x05, 0x9b, 0x01, 0x33, + 0x09, 0x93, 0x05, 0x9b, 0x5b, 0x78, 0x04, 0x93, 0x00, 0x2b, 0x28, 0xd0, + 0x04, 0x98, 0xff, 0xf7, 0x5f, 0xfd, 0x00, 0x28, 0x54, 0xd1, 0x04, 0x9b, + 0x20, 0x2b, 0x19, 0xd8, 0x03, 0x9b, 0x07, 0x9a, 0x93, 0x42, 0x12, 0xdd, + 0xbc, 0x42, 0x06, 0xd2, 0x07, 0x2d, 0x04, 0xdc, 0x2a, 0x00, 0x39, 0x00, + 0x20, 0x00, 0xff, 0xf7, 0x9f, 0xff, 0x01, 0x9b, 0x08, 0x25, 0x9c, 0x42, + 0x05, 0xd9, 0x27, 0x1f, 0x00, 0x25, 0x3c, 0x00, 0x03, 0x9b, 0x3d, 0x60, + 0x07, 0x93, 0x09, 0x9b, 0x05, 0x93, 0xd5, 0xe7, 0x04, 0x9b, 0x29, 0x2b, + 0x59, 0xd1, 0x05, 0x9b, 0x08, 0x9a, 0x02, 0x33, 0x13, 0x60, 0x03, 0x9b, + 0x00, 0x2b, 0x52, 0xd0, 0xbc, 0x42, 0x06, 0xd2, 0x07, 0x2d, 0x04, 0xdc, + 0x2a, 0x00, 0x39, 0x00, 0x20, 0x00, 0xff, 0xf7, 0x7f, 0xff, 0x01, 0x9b, + 0x9c, 0x42, 0x35, 0xd9, 0x1a, 0x00, 0x23, 0x00, 0x02, 0xcb, 0x02, 0xc2, + 0x9e, 0x42, 0xfb, 0xd2, 0x02, 0x9b, 0x61, 0x1c, 0xda, 0x1e, 0x04, 0x23, + 0x91, 0x42, 0x05, 0xd8, 0x02, 0x9b, 0x04, 0x3b, 0x1b, 0x1b, 0x9b, 0x08, + 0x01, 0x33, 0x9b, 0x00, 0x01, 0x9a, 0xd3, 0x18, 0x00, 0x22, 0x04, 0xc3, + 0x9e, 0x42, 0xfc, 0xd2, 0x33, 0x68, 0x00, 0x2b, 0x04, 0xd1, 0x01, 0x9b, + 0x9e, 0x42, 0x26, 0xd1, 0x01, 0x23, 0x33, 0x60, 0x05, 0x20, 0x25, 0xe0, + 0x03, 0x9b, 0x01, 0x35, 0x01, 0x33, 0x03, 0x93, 0x08, 0x2d, 0x06, 0xdd, + 0x01, 0x9b, 0x9c, 0x42, 0xbb, 0xd9, 0x00, 0x23, 0x01, 0x25, 0x04, 0x3c, + 0x23, 0x60, 0x0f, 0x22, 0x23, 0x68, 0x10, 0x40, 0x1b, 0x01, 0x18, 0x43, + 0x20, 0x60, 0xb0, 0xe7, 0x06, 0x9b, 0x00, 0x2b, 0xde, 0xd0, 0x20, 0x21, + 0x06, 0x9a, 0x02, 0x9b, 0x89, 0x1a, 0x01, 0x22, 0x52, 0x42, 0xca, 0x40, + 0x04, 0x3b, 0x19, 0x68, 0x0a, 0x40, 0x1a, 0x60, 0xd2, 0xe7, 0x04, 0x3e, + 0xd0, 0xe7, 0x04, 0x20, 0x0b, 0xb0, 0xf0, 0xbd, 0x70, 0xb5, 0x14, 0x1e, + 0x0b, 0x4d, 0x01, 0xd1, 0x28, 0x00, 0x70, 0xbd, 0x10, 0x00, 0x0a, 0x49, + 0x01, 0xf0, 0xd4, 0xfa, 0x00, 0x28, 0xf7, 0xd0, 0x29, 0x00, 0x20, 0x00, + 0x01, 0xf0, 0xce, 0xfa, 0x00, 0x28, 0xf1, 0xd0, 0x20, 0x00, 0x05, 0x49, + 0x01, 0xf0, 0xc8, 0xfa, 0x00, 0x28, 0xeb, 0xd0, 0x00, 0x20, 0xea, 0xe7, + 0x83, 0xfe, 0x00, 0x10, 0xd4, 0x03, 0x01, 0x10, 0x11, 0xfd, 0x00, 0x10, + 0x94, 0x23, 0x02, 0x4a, 0x5b, 0x00, 0xd0, 0x5c, 0x70, 0x47, 0xc0, 0x46, + 0xa4, 0x0a, 0x00, 0x20, 0x70, 0xb5, 0x0d, 0x00, 0x04, 0x00, 0xf6, 0xf7, + 0x13, 0xfc, 0x2a, 0x00, 0x21, 0x00, 0xff, 0xf7, 0xcf, 0xff, 0x70, 0xbd, + 0xf0, 0x30, 0x70, 0x47, 0x00, 0x48, 0x70, 0x47, 0x94, 0x0b, 0x00, 0x20, + 0x00, 0x48, 0x70, 0x47, 0x94, 0x0b, 0x00, 0x20, 0x70, 0xb5, 0x04, 0x00, + 0x08, 0x00, 0x11, 0x00, 0x1a, 0x00, 0x00, 0x23, 0x05, 0x4d, 0x2b, 0x60, + 0x01, 0xf0, 0x38, 0xfd, 0x43, 0x1c, 0x03, 0xd1, 0x2b, 0x68, 0x00, 0x2b, + 0x00, 0xd0, 0x23, 0x60, 0x70, 0xbd, 0xc0, 0x46, 0x20, 0x0e, 0x00, 0x20, + 0x37, 0xb5, 0x06, 0x9d, 0x02, 0x4c, 0x00, 0x95, 0xe4, 0x34, 0x24, 0x68, + 0xa0, 0x47, 0x3e, 0xbd, 0xa4, 0x0a, 0x00, 0x20, 0x82, 0xb0, 0x00, 0x29, + 0x00, 0xd1, 0x01, 0xa9, 0x10, 0x1e, 0x06, 0xd0, 0x00, 0x2b, 0x06, 0xd0, + 0x13, 0x78, 0x0b, 0x60, 0x10, 0x78, 0x43, 0x1e, 0x98, 0x41, 0x02, 0xb0, + 0x70, 0x47, 0x02, 0x20, 0x40, 0x42, 0xfa, 0xe7, 0x70, 0xb5, 0x45, 0x6a, + 0x06, 0x00, 0x0c, 0x00, 0x00, 0x2d, 0x0e, 0xd1, 0x10, 0x20, 0xfb, 0xf7, + 0x42, 0xfe, 0x02, 0x1e, 0x70, 0x62, 0x04, 0xd1, 0x66, 0x21, 0x19, 0x4b, + 0x19, 0x48, 0xf8, 0xf7, 0xa7, 0xfa, 0x45, 0x60, 0x85, 0x60, 0x05, 0x60, + 0xc5, 0x60, 0x75, 0x6a, 0xeb, 0x68, 0x00, 0x2b, 0x13, 0xd0, 0x73, 0x6a, + 0xa2, 0x00, 0xdb, 0x68, 0x9b, 0x18, 0x18, 0x68, 0x00, 0x28, 0x18, 0xd1, + 0x01, 0x21, 0x0d, 0x00, 0xa5, 0x40, 0x6a, 0x1d, 0x30, 0x00, 0x92, 0x00, + 0xfb, 0xf7, 0x79, 0xfc, 0x00, 0x28, 0x0c, 0xd0, 0x44, 0x60, 0x85, 0x60, + 0x0d, 0xe0, 0x21, 0x22, 0x04, 0x21, 0x30, 0x00, 0xfb, 0xf7, 0x6f, 0xfc, + 0x73, 0x6a, 0xe8, 0x60, 0xdb, 0x68, 0x00, 0x2b, 0xe1, 0xd1, 0x00, 0x20, + 0x70, 0xbd, 0x02, 0x68, 0x1a, 0x60, 0x00, 0x23, 0x03, 0x61, 0xc3, 0x60, + 0xf8, 0xe7, 0xc0, 0x46, 0x36, 0x03, 0x01, 0x10, 0xda, 0x03, 0x01, 0x10, + 0x70, 0xb5, 0x46, 0x6a, 0x05, 0x00, 0x0c, 0x00, 0x00, 0x2e, 0x0e, 0xd1, + 0x10, 0x20, 0xfb, 0xf7, 0xfe, 0xfd, 0x02, 0x1e, 0x68, 0x62, 0x04, 0xd1, + 0x8a, 0x21, 0x09, 0x4b, 0x09, 0x48, 0xf8, 0xf7, 0x63, 0xfa, 0x46, 0x60, + 0x86, 0x60, 0x06, 0x60, 0xc6, 0x60, 0x00, 0x2c, 0x07, 0xd0, 0x6b, 0x6a, + 0x62, 0x68, 0xdb, 0x68, 0x92, 0x00, 0x9b, 0x18, 0x1a, 0x68, 0x22, 0x60, + 0x1c, 0x60, 0x70, 0xbd, 0x36, 0x03, 0x01, 0x10, 0xda, 0x03, 0x01, 0x10, + 0xf7, 0xb5, 0x0e, 0x00, 0x01, 0x90, 0x0c, 0x00, 0x1d, 0x00, 0x00, 0x20, + 0x0f, 0x69, 0x14, 0x36, 0x33, 0x68, 0x01, 0x30, 0x99, 0xb2, 0x51, 0x43, + 0x1b, 0x0c, 0x53, 0x43, 0x49, 0x19, 0x0d, 0x0c, 0x5b, 0x19, 0x1d, 0x0c, + 0x89, 0xb2, 0x1b, 0x04, 0x5b, 0x18, 0x08, 0xc6, 0x87, 0x42, 0xef, 0xdc, + 0x00, 0x2d, 0x22, 0xd0, 0xa3, 0x68, 0xbb, 0x42, 0x19, 0xdc, 0x63, 0x68, + 0x01, 0x98, 0x59, 0x1c, 0xff, 0xf7, 0x76, 0xff, 0x06, 0x1e, 0x05, 0xd1, + 0x02, 0x00, 0xb5, 0x21, 0x0c, 0x4b, 0x0d, 0x48, 0xf8, 0xf7, 0x26, 0xfa, + 0x21, 0x00, 0x23, 0x69, 0x0c, 0x31, 0x9a, 0x1c, 0x92, 0x00, 0x0c, 0x30, + 0xf9, 0xf7, 0x78, 0xf9, 0x21, 0x00, 0x01, 0x98, 0xff, 0xf7, 0xa6, 0xff, + 0x34, 0x00, 0x3b, 0x1d, 0x9b, 0x00, 0xe3, 0x18, 0x5d, 0x60, 0x7b, 0x1c, + 0x23, 0x61, 0x20, 0x00, 0xfe, 0xbd, 0xc0, 0x46, 0x7c, 0x03, 0x01, 0x10, + 0xda, 0x03, 0x01, 0x10, 0xf7, 0xb5, 0x06, 0x00, 0x18, 0x00, 0x0c, 0x00, + 0x08, 0x30, 0x09, 0x21, 0x01, 0x93, 0x15, 0x00, 0xf8, 0xf7, 0x36, 0xfa, + 0x01, 0x23, 0x00, 0x21, 0x83, 0x42, 0x0a, 0xdb, 0x30, 0x00, 0xff, 0xf7, + 0x43, 0xff, 0x01, 0x1e, 0x08, 0xd1, 0x02, 0x00, 0x19, 0x4b, 0x1a, 0x48, + 0xce, 0x31, 0xf8, 0xf7, 0xf3, 0xf9, 0x5b, 0x00, 0x01, 0x31, 0xef, 0xe7, + 0x08, 0x9b, 0x43, 0x61, 0x01, 0x23, 0x03, 0x61, 0x09, 0x2d, 0x18, 0xdd, + 0x23, 0x00, 0x09, 0x33, 0x1f, 0x00, 0x00, 0x93, 0x64, 0x19, 0x3b, 0x78, + 0x0a, 0x22, 0x30, 0x00, 0x30, 0x3b, 0xff, 0xf7, 0x8f, 0xff, 0x01, 0x37, + 0x01, 0x00, 0xa7, 0x42, 0xf5, 0xd1, 0x2c, 0x00, 0x00, 0x9b, 0x08, 0x3c, + 0x1c, 0x19, 0x2f, 0x00, 0x01, 0x9b, 0x9f, 0x42, 0x04, 0xdb, 0x08, 0x00, + 0xfe, 0xbd, 0x09, 0x25, 0x0a, 0x34, 0xf6, 0xe7, 0x63, 0x1b, 0xdb, 0x5d, + 0x0a, 0x22, 0x30, 0x00, 0x30, 0x3b, 0xff, 0xf7, 0x77, 0xff, 0x01, 0x37, + 0x01, 0x00, 0xed, 0xe7, 0x7c, 0x03, 0x01, 0x10, 0xda, 0x03, 0x01, 0x10, + 0x03, 0x00, 0x02, 0x0c, 0x00, 0x20, 0x82, 0x42, 0x01, 0xd1, 0x1b, 0x04, + 0x10, 0x30, 0x1a, 0x0e, 0x01, 0xd1, 0x08, 0x30, 0x1b, 0x02, 0x1a, 0x0f, + 0x01, 0xd1, 0x04, 0x30, 0x1b, 0x01, 0x9a, 0x0f, 0x01, 0xd1, 0x02, 0x30, + 0x9b, 0x00, 0x00, 0x2b, 0x03, 0xdb, 0x01, 0x30, 0x5b, 0x00, 0x00, 0xd4, + 0x20, 0x20, 0x70, 0x47, 0x03, 0x68, 0x02, 0x00, 0x07, 0x21, 0x18, 0x00, + 0x08, 0x40, 0x0b, 0x42, 0x0d, 0xd0, 0x06, 0x39, 0x00, 0x20, 0x0b, 0x42, + 0x05, 0xd1, 0x02, 0x30, 0x03, 0x42, 0x03, 0xd0, 0xcb, 0x40, 0x08, 0x00, + 0x13, 0x60, 0x70, 0x47, 0x9b, 0x08, 0x13, 0x60, 0xfb, 0xe7, 0x99, 0xb2, + 0x00, 0x29, 0x01, 0xd1, 0x10, 0x20, 0x1b, 0x0c, 0xd9, 0xb2, 0x00, 0x29, + 0x01, 0xd1, 0x08, 0x30, 0x1b, 0x0a, 0x19, 0x07, 0x01, 0xd1, 0x04, 0x30, + 0x1b, 0x09, 0x99, 0x07, 0x01, 0xd1, 0x02, 0x30, 0x9b, 0x08, 0xd9, 0x07, + 0xe9, 0xd4, 0x01, 0x30, 0x5b, 0x08, 0xe6, 0xd1, 0x20, 0x20, 0xe2, 0xe7, + 0x10, 0xb5, 0x0c, 0x00, 0x01, 0x21, 0xff, 0xf7, 0xbb, 0xfe, 0x00, 0x28, + 0x06, 0xd1, 0xa0, 0x21, 0x02, 0x00, 0x04, 0x4b, 0x04, 0x48, 0x49, 0x00, + 0xf8, 0xf7, 0x6a, 0xf9, 0x01, 0x23, 0x44, 0x61, 0x03, 0x61, 0x10, 0xbd, + 0x7c, 0x03, 0x01, 0x10, 0xda, 0x03, 0x01, 0x10, 0xf0, 0xb5, 0x0b, 0x69, + 0x14, 0x00, 0x12, 0x69, 0x0d, 0x00, 0x89, 0xb0, 0x93, 0x42, 0x01, 0xda, + 0x25, 0x00, 0x0c, 0x00, 0x2f, 0x69, 0x26, 0x69, 0x69, 0x68, 0xbb, 0x19, + 0x02, 0x93, 0xab, 0x68, 0xba, 0x19, 0x93, 0x42, 0x00, 0xda, 0x01, 0x31, + 0xff, 0xf7, 0x94, 0xfe, 0x01, 0x90, 0x00, 0x28, 0x06, 0xd1, 0x5e, 0x21, + 0x02, 0x00, 0x48, 0x4b, 0x48, 0x48, 0xff, 0x31, 0xf8, 0xf7, 0x42, 0xf9, + 0x01, 0x9b, 0x00, 0x22, 0x14, 0x33, 0x9c, 0x46, 0xbb, 0x19, 0x9b, 0x00, + 0x63, 0x44, 0x03, 0x93, 0x63, 0x46, 0x03, 0x99, 0x8b, 0x42, 0x2c, 0xd3, + 0x2b, 0x00, 0x22, 0x00, 0x14, 0x33, 0xbf, 0x00, 0x14, 0x32, 0x06, 0x93, + 0xb6, 0x00, 0xdb, 0x19, 0x04, 0x93, 0x93, 0x19, 0x07, 0x93, 0x04, 0x23, + 0x05, 0x93, 0x2b, 0x00, 0x04, 0x99, 0x15, 0x33, 0x00, 0x92, 0x99, 0x42, + 0x05, 0xd3, 0x4b, 0x1b, 0x15, 0x3b, 0x9b, 0x08, 0x01, 0x33, 0x9b, 0x00, + 0x05, 0x93, 0x07, 0x9b, 0x00, 0x9a, 0x9a, 0x42, 0x11, 0xd3, 0x02, 0x9b, + 0x00, 0x2b, 0x06, 0xdd, 0x03, 0x9b, 0x04, 0x3b, 0x03, 0x93, 0x1b, 0x68, + 0x00, 0x93, 0x00, 0x2b, 0x53, 0xd0, 0x01, 0x9b, 0x02, 0x9a, 0x18, 0x00, + 0x1a, 0x61, 0x09, 0xb0, 0xf0, 0xbd, 0x04, 0xc3, 0xcd, 0xe7, 0x00, 0x9b, + 0x1b, 0x68, 0x98, 0xb2, 0x00, 0x28, 0x1b, 0xd0, 0x67, 0x46, 0x00, 0x24, + 0x06, 0x9e, 0x02, 0xce, 0x3a, 0x68, 0x8b, 0xb2, 0x43, 0x43, 0x92, 0xb2, + 0x9b, 0x18, 0x1b, 0x19, 0x0c, 0x0c, 0x44, 0x43, 0x3a, 0x68, 0x11, 0x0c, + 0x61, 0x18, 0x1c, 0x0c, 0x09, 0x19, 0x0c, 0x0c, 0x9b, 0xb2, 0x09, 0x04, + 0x0b, 0x43, 0x08, 0xc7, 0x04, 0x9b, 0xb3, 0x42, 0xe9, 0xd8, 0x63, 0x46, + 0x05, 0x9a, 0x9c, 0x50, 0x00, 0x9b, 0x1b, 0x68, 0x1e, 0x0c, 0x20, 0xd0, + 0x63, 0x46, 0x2c, 0x00, 0x60, 0x46, 0x00, 0x27, 0x1b, 0x68, 0x14, 0x34, + 0x22, 0x68, 0x9b, 0xb2, 0x91, 0xb2, 0x71, 0x43, 0x02, 0x68, 0x12, 0x0c, + 0x89, 0x18, 0xcf, 0x19, 0x39, 0x04, 0x0b, 0x43, 0x03, 0x60, 0x02, 0xcc, + 0x43, 0x68, 0x09, 0x0c, 0x71, 0x43, 0x9b, 0xb2, 0x3f, 0x0c, 0xcb, 0x18, + 0x04, 0x9a, 0xdb, 0x19, 0x1f, 0x0c, 0x04, 0x30, 0xa2, 0x42, 0xe7, 0xd8, + 0x62, 0x46, 0x05, 0x99, 0x53, 0x50, 0x00, 0x9b, 0x04, 0x33, 0x00, 0x93, + 0x04, 0x23, 0x9c, 0x44, 0x9d, 0xe7, 0x02, 0x9b, 0x01, 0x3b, 0x02, 0x93, + 0x9d, 0xe7, 0xc0, 0x46, 0x7c, 0x03, 0x01, 0x10, 0xda, 0x03, 0x01, 0x10, + 0xf7, 0xb5, 0x03, 0x23, 0x15, 0x00, 0x07, 0x00, 0x0e, 0x00, 0x1a, 0x40, + 0x1d, 0x42, 0x08, 0xd0, 0x25, 0x49, 0x01, 0x3a, 0x92, 0x00, 0x52, 0x58, + 0x00, 0x23, 0x31, 0x00, 0xff, 0xf7, 0x52, 0xfe, 0x06, 0x00, 0xad, 0x10, + 0x3d, 0xd0, 0x7c, 0x6a, 0x00, 0x2c, 0x0f, 0xd1, 0x10, 0x20, 0xfb, 0xf7, + 0x2c, 0xfc, 0x02, 0x1e, 0x78, 0x62, 0x05, 0xd1, 0xd7, 0x21, 0x1c, 0x4b, + 0x1c, 0x48, 0x49, 0x00, 0xf8, 0xf7, 0x90, 0xf8, 0x44, 0x60, 0x84, 0x60, + 0x04, 0x60, 0xc4, 0x60, 0x7b, 0x6a, 0x9c, 0x68, 0x01, 0x93, 0x00, 0x2c, + 0x08, 0xd1, 0x38, 0x00, 0x16, 0x49, 0xff, 0xf7, 0x0b, 0xff, 0x01, 0x9b, + 0x04, 0x00, 0x98, 0x60, 0x00, 0x23, 0x03, 0x60, 0x01, 0x23, 0x1d, 0x42, + 0x0a, 0xd0, 0x31, 0x00, 0x22, 0x00, 0x38, 0x00, 0xff, 0xf7, 0x14, 0xff, + 0x31, 0x00, 0x01, 0x90, 0x38, 0x00, 0xff, 0xf7, 0xfd, 0xfd, 0x01, 0x9e, + 0x6d, 0x10, 0x0c, 0xd0, 0x20, 0x68, 0x00, 0x28, 0x07, 0xd1, 0x22, 0x00, + 0x21, 0x00, 0x38, 0x00, 0xff, 0xf7, 0x04, 0xff, 0x00, 0x23, 0x20, 0x60, + 0x03, 0x60, 0x04, 0x00, 0xe2, 0xe7, 0x30, 0x00, 0xfe, 0xbd, 0xc0, 0x46, + 0x10, 0x04, 0x01, 0x10, 0x36, 0x03, 0x01, 0x10, 0xda, 0x03, 0x01, 0x10, + 0x71, 0x02, 0x00, 0x00, 0xf0, 0xb5, 0x0c, 0x00, 0x17, 0x00, 0x23, 0x69, + 0x55, 0x11, 0x87, 0xb0, 0xeb, 0x18, 0x02, 0x93, 0x01, 0x33, 0x01, 0x93, + 0x49, 0x68, 0xa3, 0x68, 0x04, 0x90, 0x01, 0x9a, 0x93, 0x42, 0x10, 0xdb, + 0x04, 0x98, 0xff, 0xf7, 0x8b, 0xfd, 0x00, 0x23, 0x02, 0x00, 0x06, 0x00, + 0x19, 0x00, 0x14, 0x32, 0x98, 0x42, 0x0c, 0xd1, 0xda, 0x21, 0x02, 0x00, + 0x26, 0x4b, 0x27, 0x48, 0xff, 0x31, 0xf8, 0xf7, 0x35, 0xf8, 0x01, 0x31, + 0x5b, 0x00, 0xe8, 0xe7, 0x98, 0x00, 0x11, 0x50, 0x01, 0x33, 0xab, 0x42, + 0xfa, 0xdb, 0xeb, 0x43, 0xdb, 0x17, 0x1d, 0x40, 0x1f, 0x21, 0x23, 0x00, + 0x38, 0x00, 0xad, 0x00, 0x55, 0x19, 0x22, 0x69, 0x14, 0x33, 0x92, 0x00, + 0x08, 0x40, 0x84, 0x46, 0x9a, 0x18, 0x0f, 0x42, 0x2a, 0xd0, 0x01, 0x31, + 0x09, 0x1a, 0x05, 0x91, 0x00, 0x21, 0x03, 0x95, 0x67, 0x46, 0x18, 0x68, + 0xb8, 0x40, 0x01, 0x43, 0x03, 0x98, 0x02, 0xc0, 0x02, 0xcb, 0x03, 0x90, + 0x05, 0x98, 0xc1, 0x40, 0x9a, 0x42, 0xf3, 0xd8, 0x20, 0x00, 0x15, 0x30, + 0x04, 0x23, 0x82, 0x42, 0x04, 0xd3, 0x13, 0x1b, 0x15, 0x3b, 0x9b, 0x08, + 0x01, 0x33, 0x9b, 0x00, 0xe9, 0x50, 0x00, 0x29, 0x02, 0xd0, 0x02, 0x9b, + 0x02, 0x33, 0x01, 0x93, 0x01, 0x9b, 0x04, 0x98, 0x01, 0x3b, 0x21, 0x00, + 0x33, 0x61, 0xff, 0xf7, 0x81, 0xfd, 0x30, 0x00, 0x07, 0xb0, 0xf0, 0xbd, + 0x02, 0xcb, 0x02, 0xc5, 0x9a, 0x42, 0xfb, 0xd8, 0xf0, 0xe7, 0xc0, 0x46, + 0x7c, 0x03, 0x01, 0x10, 0xda, 0x03, 0x01, 0x10, 0x02, 0x69, 0x0b, 0x69, + 0x30, 0xb5, 0x04, 0x00, 0xd0, 0x1a, 0x9a, 0x42, 0x0d, 0xd1, 0x9b, 0x00, + 0x14, 0x34, 0x14, 0x31, 0xe2, 0x18, 0xc9, 0x18, 0x04, 0x3a, 0x04, 0x39, + 0x15, 0x68, 0x0b, 0x68, 0x9d, 0x42, 0x03, 0xd0, 0x01, 0x20, 0x9d, 0x42, + 0x03, 0xd3, 0x30, 0xbd, 0x94, 0x42, 0xf3, 0xd3, 0xfb, 0xe7, 0x40, 0x42, + 0xf9, 0xe7, 0xf0, 0xb5, 0x0e, 0x00, 0x07, 0x00, 0x11, 0x00, 0x30, 0x00, + 0x87, 0xb0, 0x14, 0x00, 0xff, 0xf7, 0xdc, 0xff, 0x05, 0x1e, 0x10, 0xd1, + 0x01, 0x00, 0x38, 0x00, 0xff, 0xf7, 0x06, 0xfd, 0x02, 0x1e, 0x04, 0xd1, + 0x3f, 0x4b, 0x40, 0x49, 0x40, 0x48, 0xf7, 0xf7, 0xb7, 0xff, 0x01, 0x23, + 0x45, 0x61, 0x03, 0x61, 0x10, 0x00, 0x07, 0xb0, 0xf0, 0xbd, 0x01, 0x23, + 0x01, 0x93, 0x00, 0x28, 0x04, 0xdb, 0x23, 0x00, 0x34, 0x00, 0x1e, 0x00, + 0x00, 0x23, 0x01, 0x93, 0x38, 0x00, 0x61, 0x68, 0xff, 0xf7, 0xec, 0xfc, + 0x02, 0x1e, 0x03, 0xd1, 0x90, 0x21, 0x32, 0x4b, 0x89, 0x00, 0xe3, 0xe7, + 0x01, 0x9b, 0x00, 0x27, 0xc3, 0x60, 0x20, 0x69, 0x14, 0x34, 0x01, 0x94, + 0x01, 0x9b, 0x84, 0x00, 0x1b, 0x19, 0x34, 0x00, 0x02, 0x93, 0x33, 0x69, + 0x14, 0x34, 0x99, 0x00, 0x63, 0x18, 0x03, 0x93, 0x13, 0x00, 0x14, 0x33, + 0x9c, 0x46, 0x05, 0x93, 0x01, 0x9b, 0x04, 0x93, 0x04, 0x9b, 0x02, 0xcc, + 0x20, 0xcb, 0x04, 0x93, 0xab, 0xb2, 0xdf, 0x19, 0x8b, 0xb2, 0xfb, 0x1a, + 0x09, 0x0c, 0x2d, 0x0c, 0x6d, 0x1a, 0x19, 0x14, 0x6d, 0x18, 0x61, 0x46, + 0x2f, 0x14, 0x9b, 0xb2, 0x2d, 0x04, 0x2b, 0x43, 0x08, 0xc1, 0x03, 0x9b, + 0x8c, 0x46, 0xa3, 0x42, 0xe8, 0xd8, 0x31, 0x00, 0x03, 0x9c, 0x15, 0x31, + 0x04, 0x23, 0x8c, 0x42, 0x04, 0xd3, 0xa3, 0x1b, 0x15, 0x3b, 0x9b, 0x08, + 0x01, 0x33, 0x9b, 0x00, 0x01, 0x99, 0xcc, 0x18, 0x05, 0x99, 0x26, 0x00, + 0xcb, 0x18, 0x9c, 0x46, 0x02, 0x99, 0x8e, 0x42, 0x10, 0xd3, 0x02, 0x9e, + 0xe1, 0x1e, 0x00, 0x25, 0x8e, 0x42, 0x04, 0xd3, 0x31, 0x00, 0x03, 0x31, + 0x0c, 0x1b, 0xa4, 0x08, 0xa5, 0x00, 0x5b, 0x19, 0x04, 0x3b, 0x19, 0x68, + 0x00, 0x29, 0x0f, 0xd0, 0x10, 0x61, 0x97, 0xe7, 0x02, 0xce, 0x8d, 0xb2, + 0xed, 0x19, 0x0f, 0x0c, 0x29, 0x14, 0x79, 0x18, 0x0f, 0x14, 0xad, 0xb2, + 0x09, 0x04, 0x0d, 0x43, 0x61, 0x46, 0x20, 0xc1, 0x8c, 0x46, 0xdd, 0xe7, + 0x01, 0x38, 0xe9, 0xe7, 0x7c, 0x03, 0x01, 0x10, 0x32, 0x02, 0x00, 0x00, + 0xda, 0x03, 0x01, 0x10, 0x0f, 0x4b, 0x19, 0x40, 0x0f, 0x4b, 0xc9, 0x18, + 0x00, 0x29, 0x04, 0xdd, 0x00, 0x22, 0x0b, 0x00, 0x10, 0x00, 0x19, 0x00, + 0x70, 0x47, 0x49, 0x42, 0x00, 0x22, 0x00, 0x23, 0x09, 0x15, 0x13, 0x29, + 0x04, 0xdc, 0x80, 0x20, 0x00, 0x03, 0x08, 0x41, 0x03, 0x00, 0xf1, 0xe7, + 0x14, 0x39, 0x01, 0x20, 0x1e, 0x29, 0x02, 0xdc, 0x80, 0x20, 0x00, 0x06, + 0xc8, 0x40, 0x02, 0x00, 0xe8, 0xe7, 0xc0, 0x46, 0x00, 0x00, 0xf0, 0x7f, + 0x00, 0x00, 0xc0, 0xfc, 0xf7, 0xb5, 0x06, 0x00, 0x03, 0x69, 0x14, 0x36, + 0x9b, 0x00, 0xf3, 0x18, 0x1d, 0x1f, 0x2c, 0x68, 0x0f, 0x00, 0x20, 0x00, + 0x01, 0x93, 0xff, 0xf7, 0x45, 0xfd, 0x20, 0x23, 0x1b, 0x1a, 0x1f, 0x49, + 0x3b, 0x60, 0x0a, 0x28, 0x16, 0xdc, 0x0b, 0x23, 0x27, 0x00, 0x1b, 0x1a, + 0xdf, 0x40, 0x39, 0x43, 0x9c, 0x46, 0x0b, 0x00, 0x00, 0x21, 0xae, 0x42, + 0x02, 0xd2, 0x01, 0x99, 0x08, 0x39, 0x09, 0x68, 0x15, 0x30, 0x84, 0x40, + 0x60, 0x46, 0xc1, 0x40, 0x0c, 0x43, 0x22, 0x00, 0x10, 0x00, 0x19, 0x00, + 0x03, 0xb0, 0xf0, 0xbd, 0x00, 0x27, 0xae, 0x42, 0x02, 0xd2, 0x01, 0x9d, + 0x08, 0x3d, 0x2f, 0x68, 0x0b, 0x23, 0x5b, 0x42, 0x9c, 0x46, 0x84, 0x44, + 0x0b, 0x28, 0x13, 0xd0, 0x63, 0x46, 0x20, 0x20, 0x9c, 0x40, 0xc0, 0x1a, + 0x3b, 0x00, 0xc3, 0x40, 0x1c, 0x43, 0x21, 0x43, 0x0b, 0x00, 0x00, 0x21, + 0xb5, 0x42, 0x01, 0xd9, 0x04, 0x3d, 0x29, 0x68, 0x64, 0x46, 0xc1, 0x40, + 0xa7, 0x40, 0x0f, 0x43, 0x3a, 0x00, 0xdb, 0xe7, 0x21, 0x43, 0x0b, 0x00, + 0xfa, 0xe7, 0xc0, 0x46, 0x00, 0x00, 0xf0, 0x3f, 0xf7, 0xb5, 0x01, 0x21, + 0x14, 0x00, 0x1e, 0x00, 0x08, 0x9f, 0xff, 0xf7, 0x03, 0xfc, 0x05, 0x1e, + 0x05, 0xd1, 0x02, 0x00, 0x26, 0x4b, 0x27, 0x49, 0x27, 0x48, 0xf7, 0xf7, + 0xb3, 0xfe, 0x33, 0x03, 0x76, 0x00, 0x1b, 0x0b, 0x76, 0x0d, 0x24, 0xd1, + 0x01, 0x93, 0x00, 0x2c, 0x27, 0xd0, 0x68, 0x46, 0x00, 0x94, 0xff, 0xf7, + 0x01, 0xfd, 0x00, 0x9c, 0x00, 0x28, 0x1e, 0xd0, 0x01, 0x9b, 0x20, 0x21, + 0x1a, 0x00, 0x09, 0x1a, 0x8a, 0x40, 0xc3, 0x40, 0x22, 0x43, 0x6a, 0x61, + 0x01, 0x93, 0x01, 0x9c, 0xac, 0x61, 0x63, 0x1e, 0x9c, 0x41, 0x01, 0x34, + 0x2c, 0x61, 0x00, 0x2e, 0x18, 0xd0, 0x17, 0x4b, 0xf6, 0x18, 0x35, 0x23, + 0x36, 0x18, 0x18, 0x1a, 0x09, 0x9b, 0x3e, 0x60, 0x18, 0x60, 0x28, 0x00, + 0xfe, 0xbd, 0x80, 0x22, 0x52, 0x03, 0x13, 0x43, 0xd6, 0xe7, 0x6c, 0x61, + 0xe7, 0xe7, 0x01, 0xa8, 0xff, 0xf7, 0xda, 0xfc, 0x01, 0x24, 0x01, 0x9b, + 0x2c, 0x61, 0x6b, 0x61, 0x20, 0x30, 0xe4, 0xe7, 0x0b, 0x4b, 0xc0, 0x18, + 0x0b, 0x4b, 0x38, 0x60, 0xe3, 0x18, 0x9b, 0x00, 0xeb, 0x18, 0x58, 0x69, + 0xff, 0xf7, 0xb0, 0xfc, 0x64, 0x01, 0x09, 0x9b, 0x24, 0x1a, 0x1c, 0x60, + 0xdf, 0xe7, 0xc0, 0x46, 0x7c, 0x03, 0x01, 0x10, 0x0a, 0x03, 0x00, 0x00, + 0xda, 0x03, 0x01, 0x10, 0xcd, 0xfb, 0xff, 0xff, 0xce, 0xfb, 0xff, 0xff, + 0xff, 0xff, 0xff, 0x3f, 0xf0, 0xb5, 0x87, 0xb0, 0x0f, 0x00, 0x04, 0xa9, + 0x06, 0x00, 0xff, 0xf7, 0x45, 0xff, 0x00, 0x90, 0x01, 0x91, 0x00, 0x9c, + 0x01, 0x9d, 0x38, 0x00, 0x05, 0xa9, 0xff, 0xf7, 0x3d, 0xff, 0x02, 0x90, + 0x03, 0x91, 0x02, 0x9a, 0x03, 0x9b, 0x31, 0x69, 0x38, 0x69, 0x05, 0x9e, + 0x08, 0x1a, 0x04, 0x99, 0x40, 0x01, 0x89, 0x1b, 0x41, 0x18, 0x08, 0x05, + 0x00, 0x29, 0x07, 0xdd, 0x01, 0x99, 0x45, 0x18, 0x20, 0x00, 0x29, 0x00, + 0xf8, 0xf7, 0xeb, 0xf8, 0x07, 0xb0, 0xf0, 0xbd, 0x03, 0x99, 0x0b, 0x1a, + 0xf6, 0xe7, 0x10, 0xb5, 0x04, 0x00, 0x17, 0x28, 0x05, 0xdc, 0x08, 0x4c, + 0xc0, 0x00, 0x24, 0x18, 0x20, 0x68, 0x61, 0x68, 0x10, 0xbd, 0x00, 0x20, + 0x05, 0x49, 0x00, 0x22, 0x05, 0x4b, 0x01, 0x3c, 0xf8, 0xf7, 0xf3, 0xf8, + 0x00, 0x2c, 0xf8, 0xd1, 0xf4, 0xe7, 0xc0, 0x46, 0x70, 0x04, 0x01, 0x10, + 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x24, 0x40, 0x70, 0xb5, 0x14, 0x00, + 0x05, 0x00, 0x01, 0x39, 0x13, 0x69, 0x49, 0x11, 0x01, 0x31, 0x89, 0x00, + 0x14, 0x34, 0x9b, 0x00, 0x41, 0x18, 0xe3, 0x18, 0xa3, 0x42, 0x0d, 0xd8, + 0x14, 0x00, 0x11, 0x34, 0x00, 0x25, 0x9c, 0x42, 0x03, 0xd8, 0x9b, 0x1a, + 0x11, 0x3b, 0x9b, 0x08, 0x9d, 0x00, 0x00, 0x23, 0x40, 0x19, 0x81, 0x42, + 0x03, 0xd8, 0x70, 0xbd, 0x40, 0xcc, 0x40, 0xc5, 0xec, 0xe7, 0x08, 0xc0, + 0xf7, 0xe7, 0x02, 0x00, 0x00, 0x69, 0x10, 0xb5, 0x14, 0x32, 0x4b, 0x11, + 0x98, 0x42, 0x13, 0xdb, 0x0c, 0xdd, 0x1f, 0x24, 0x08, 0x00, 0x20, 0x40, + 0x21, 0x42, 0x07, 0xd0, 0x99, 0x00, 0x8c, 0x58, 0x21, 0x00, 0xc1, 0x40, + 0x81, 0x40, 0x01, 0x20, 0x8c, 0x42, 0x04, 0xd1, 0x9b, 0x00, 0xd3, 0x18, + 0x93, 0x42, 0x03, 0xd8, 0x00, 0x20, 0x10, 0xbd, 0x03, 0x00, 0xf7, 0xe7, + 0x04, 0x3b, 0x19, 0x68, 0x00, 0x29, 0xf5, 0xd0, 0x01, 0x20, 0xf6, 0xe7, + 0xf0, 0xb5, 0x8e, 0x68, 0x85, 0xb0, 0x07, 0x00, 0x0c, 0x00, 0x03, 0x92, + 0x01, 0x93, 0x9e, 0x42, 0x3c, 0xd8, 0x90, 0x23, 0x8a, 0x89, 0xdb, 0x00, + 0x1a, 0x42, 0x34, 0xd0, 0x09, 0x69, 0x23, 0x68, 0x60, 0x69, 0x5b, 0x1a, + 0x02, 0x93, 0x03, 0x23, 0x43, 0x43, 0xdd, 0x0f, 0xed, 0x18, 0x01, 0x9b, + 0x02, 0x98, 0x01, 0x33, 0x1b, 0x18, 0x6d, 0x10, 0xab, 0x42, 0x00, 0xd9, + 0x1d, 0x00, 0x53, 0x05, 0x32, 0xd5, 0x29, 0x00, 0x38, 0x00, 0xfb, 0xf7, + 0x55, 0xf9, 0x06, 0x1e, 0x09, 0xd1, 0x0c, 0x23, 0x3b, 0x60, 0x40, 0x23, + 0x01, 0x20, 0xa2, 0x89, 0x40, 0x42, 0x13, 0x43, 0xa3, 0x81, 0x05, 0xb0, + 0xf0, 0xbd, 0x02, 0x9a, 0x21, 0x69, 0xf8, 0xf7, 0xfb, 0xfc, 0xa3, 0x89, + 0x14, 0x4a, 0x1a, 0x40, 0x80, 0x23, 0x13, 0x43, 0xa3, 0x81, 0x02, 0x9b, + 0x26, 0x61, 0xf6, 0x18, 0x26, 0x60, 0x65, 0x61, 0x01, 0x9e, 0xed, 0x1a, + 0xa5, 0x60, 0x01, 0x9b, 0x9e, 0x42, 0x00, 0xd9, 0x01, 0x9e, 0x32, 0x00, + 0x03, 0x99, 0x20, 0x68, 0x01, 0xf0, 0xda, 0xf8, 0xa3, 0x68, 0x00, 0x20, + 0x9b, 0x1b, 0xa3, 0x60, 0x23, 0x68, 0x9e, 0x19, 0x26, 0x60, 0xda, 0xe7, + 0x2a, 0x00, 0x38, 0x00, 0x00, 0xf0, 0x90, 0xfb, 0x06, 0x1e, 0xe0, 0xd1, + 0x38, 0x00, 0x21, 0x69, 0xfe, 0xf7, 0xc6, 0xfc, 0xc7, 0xe7, 0xc0, 0x46, + 0x7f, 0xfb, 0xff, 0xff, 0xf0, 0xb5, 0x93, 0x68, 0x87, 0xb0, 0x0c, 0x00, + 0x17, 0x00, 0x02, 0x90, 0x00, 0x2b, 0x65, 0xd0, 0x13, 0x68, 0x03, 0x93, + 0x00, 0x23, 0x05, 0x93, 0x01, 0x93, 0x01, 0x9b, 0x00, 0x2b, 0x2d, 0xd0, + 0xa6, 0x68, 0x9e, 0x42, 0x49, 0xd8, 0x90, 0x23, 0xa2, 0x89, 0xdb, 0x00, + 0x1a, 0x42, 0x41, 0xd0, 0x03, 0x20, 0x21, 0x69, 0x23, 0x68, 0x5b, 0x1a, + 0x04, 0x93, 0x63, 0x69, 0x43, 0x43, 0xdd, 0x0f, 0xed, 0x18, 0x04, 0x9b, + 0x01, 0x98, 0x01, 0x33, 0x1b, 0x18, 0x6d, 0x10, 0xab, 0x42, 0x00, 0xd9, + 0x1d, 0x00, 0x53, 0x05, 0x46, 0xd5, 0x29, 0x00, 0x02, 0x98, 0xfb, 0xf7, + 0xe9, 0xf8, 0x06, 0x1e, 0x16, 0xd1, 0x0c, 0x23, 0x02, 0x9a, 0x01, 0x20, + 0x13, 0x60, 0x40, 0x23, 0xa2, 0x89, 0x40, 0x42, 0x13, 0x43, 0xa3, 0x81, + 0x00, 0x23, 0xbb, 0x60, 0x7b, 0x60, 0x31, 0xe0, 0x03, 0x9b, 0x1b, 0x68, + 0x05, 0x93, 0x03, 0x9b, 0x5b, 0x68, 0x01, 0x93, 0x03, 0x9b, 0x08, 0x33, + 0x03, 0x93, 0xc4, 0xe7, 0x04, 0x9a, 0x21, 0x69, 0xf8, 0xf7, 0x82, 0xfc, + 0xa3, 0x89, 0x18, 0x4a, 0x1a, 0x40, 0x80, 0x23, 0x13, 0x43, 0xa3, 0x81, + 0x04, 0x9b, 0x26, 0x61, 0xf6, 0x18, 0x26, 0x60, 0x65, 0x61, 0x01, 0x9e, + 0xed, 0x1a, 0xa5, 0x60, 0x01, 0x9b, 0x9e, 0x42, 0x00, 0xd9, 0x01, 0x9e, + 0x32, 0x00, 0x05, 0x99, 0x20, 0x68, 0x01, 0xf0, 0x61, 0xf8, 0xa3, 0x68, + 0x01, 0x9a, 0x9b, 0x1b, 0xa3, 0x60, 0x23, 0x68, 0x9e, 0x19, 0xbb, 0x68, + 0x26, 0x60, 0x9b, 0x1a, 0xbb, 0x60, 0xcf, 0xd1, 0x00, 0x20, 0x78, 0x60, + 0x07, 0xb0, 0xf0, 0xbd, 0x2a, 0x00, 0x02, 0x98, 0x00, 0xf0, 0x10, 0xfb, + 0x06, 0x1e, 0xd9, 0xd1, 0x21, 0x69, 0x02, 0x98, 0xfe, 0xf7, 0x46, 0xfc, + 0xb3, 0xe7, 0xc0, 0x46, 0x7f, 0xfb, 0xff, 0xff, 0xf0, 0xb5, 0xa1, 0xb0, + 0x03, 0x90, 0x1c, 0x00, 0x8b, 0x89, 0x0f, 0x00, 0x16, 0x00, 0x1b, 0x06, + 0x11, 0xd5, 0x0b, 0x69, 0x00, 0x2b, 0x0e, 0xd1, 0x40, 0x21, 0xfb, 0xf7, + 0x89, 0xf8, 0x38, 0x60, 0x38, 0x61, 0x00, 0x28, 0x05, 0xd1, 0x0c, 0x23, + 0x03, 0x9a, 0x01, 0x38, 0x13, 0x60, 0x21, 0xb0, 0xf0, 0xbd, 0x40, 0x23, + 0x7b, 0x61, 0x00, 0x23, 0x08, 0xad, 0x6b, 0x61, 0x20, 0x33, 0x6b, 0x76, + 0x10, 0x33, 0xab, 0x76, 0x07, 0x94, 0x34, 0x00, 0x23, 0x78, 0x00, 0x2b, + 0x01, 0xd0, 0x25, 0x2b, 0x48, 0xd1, 0xa3, 0x1b, 0x05, 0x93, 0xb4, 0x42, + 0x0c, 0xd0, 0x32, 0x00, 0x39, 0x00, 0x03, 0x98, 0xff, 0xf7, 0xec, 0xfe, + 0x43, 0x1c, 0x00, 0xd1, 0xcf, 0xe0, 0x6a, 0x69, 0x05, 0x9b, 0x94, 0x46, + 0x63, 0x44, 0x6b, 0x61, 0x23, 0x78, 0x00, 0x2b, 0x00, 0xd1, 0xc6, 0xe0, + 0x01, 0x22, 0x00, 0x23, 0x52, 0x42, 0x6a, 0x60, 0x04, 0xa9, 0x54, 0x32, + 0x52, 0x18, 0x01, 0x34, 0x2b, 0x60, 0xeb, 0x60, 0xab, 0x60, 0x13, 0x70, + 0xab, 0x65, 0x65, 0x4e, 0x05, 0x22, 0x30, 0x00, 0x21, 0x78, 0x00, 0xf0, + 0xa3, 0xff, 0x62, 0x1c, 0x00, 0x28, 0x1f, 0xd1, 0x29, 0x68, 0xcb, 0x06, + 0x04, 0xd5, 0x53, 0x23, 0x04, 0xa8, 0x1b, 0x18, 0x20, 0x20, 0x18, 0x70, + 0x0b, 0x07, 0x04, 0xd5, 0x53, 0x23, 0x04, 0xa8, 0x1b, 0x18, 0x2b, 0x20, + 0x18, 0x70, 0x23, 0x78, 0x2a, 0x2b, 0x15, 0xd0, 0x0a, 0x21, 0x22, 0x78, + 0x60, 0x1c, 0x30, 0x3a, 0x09, 0x2a, 0x17, 0xd8, 0xeb, 0x68, 0x04, 0x00, + 0x4b, 0x43, 0x9b, 0x18, 0xeb, 0x60, 0xf4, 0xe7, 0x01, 0x34, 0xaf, 0xe7, + 0x01, 0x23, 0x80, 0x1b, 0x83, 0x40, 0x29, 0x68, 0x14, 0x00, 0x0b, 0x43, + 0x2b, 0x60, 0xce, 0xe7, 0x07, 0x9b, 0x18, 0x1d, 0x1b, 0x68, 0x07, 0x90, + 0x00, 0x2b, 0x5e, 0xdb, 0x0b, 0x93, 0x14, 0x00, 0x23, 0x78, 0x2e, 0x2b, + 0x0a, 0xd1, 0x63, 0x78, 0x2a, 0x2b, 0x5f, 0xd1, 0x07, 0x9b, 0x02, 0x34, + 0x1a, 0x1d, 0x1b, 0x68, 0x07, 0x92, 0x00, 0x2b, 0x55, 0xdb, 0x09, 0x93, + 0x42, 0x4e, 0x03, 0x22, 0x30, 0x00, 0x21, 0x78, 0x00, 0xf0, 0x5c, 0xff, + 0x00, 0x28, 0x06, 0xd0, 0x40, 0x23, 0x80, 0x1b, 0x83, 0x40, 0x2a, 0x68, + 0x01, 0x34, 0x13, 0x43, 0x2b, 0x60, 0x80, 0x22, 0x2b, 0x68, 0x13, 0x42, + 0x08, 0xd0, 0x21, 0x78, 0x6c, 0x29, 0x05, 0xd1, 0x93, 0x43, 0x80, 0x22, + 0x12, 0x01, 0x13, 0x43, 0x01, 0x34, 0x2b, 0x60, 0x40, 0x22, 0x2b, 0x68, + 0x13, 0x42, 0x08, 0xd0, 0x21, 0x78, 0x68, 0x29, 0x05, 0xd1, 0x93, 0x43, + 0xc1, 0x32, 0xff, 0x32, 0x13, 0x43, 0x01, 0x34, 0x2b, 0x60, 0x23, 0x78, + 0x7a, 0x2b, 0x01, 0xd0, 0x74, 0x2b, 0x00, 0xd1, 0x01, 0x34, 0x23, 0x78, + 0x6a, 0x2b, 0x05, 0xd1, 0x80, 0x23, 0x2a, 0x68, 0x1b, 0x01, 0x13, 0x43, + 0x01, 0x34, 0x2b, 0x60, 0x21, 0x78, 0x06, 0x22, 0x26, 0x48, 0x66, 0x1c, + 0x29, 0x76, 0x00, 0xf0, 0x23, 0xff, 0x00, 0x28, 0x39, 0xd0, 0x24, 0x4b, + 0x00, 0x2b, 0x22, 0xd1, 0x07, 0x22, 0x07, 0x9b, 0x07, 0x33, 0x93, 0x43, + 0x08, 0x33, 0x07, 0x93, 0x6b, 0x69, 0x04, 0x9a, 0x9b, 0x18, 0x6b, 0x61, + 0x41, 0xe7, 0x5b, 0x42, 0xeb, 0x60, 0x02, 0x23, 0x0b, 0x43, 0x2b, 0x60, + 0x9b, 0xe7, 0x01, 0x23, 0x5b, 0x42, 0xa6, 0xe7, 0x00, 0x23, 0x0a, 0x21, + 0x01, 0x34, 0x09, 0x93, 0x22, 0x78, 0x60, 0x1c, 0x30, 0x3a, 0x09, 0x2a, + 0x9e, 0xd8, 0x6b, 0x68, 0x04, 0x00, 0x4b, 0x43, 0x9b, 0x18, 0x6b, 0x60, + 0xf4, 0xe7, 0x07, 0xab, 0x00, 0x93, 0x3a, 0x00, 0x29, 0x00, 0x10, 0x4b, + 0x03, 0x98, 0xfb, 0xf7, 0x61, 0xfa, 0x04, 0x90, 0x04, 0x9b, 0x01, 0x33, + 0xd6, 0xd1, 0xbb, 0x89, 0x0d, 0x98, 0x5b, 0x06, 0x00, 0xd4, 0x0c, 0xe7, + 0x01, 0x20, 0x40, 0x42, 0x09, 0xe7, 0x07, 0xab, 0x00, 0x93, 0x3a, 0x00, + 0x29, 0x00, 0x06, 0x4b, 0x03, 0x98, 0xfb, 0xf7, 0x0a, 0xfd, 0xea, 0xe7, + 0x38, 0x05, 0x01, 0x10, 0x3e, 0x05, 0x01, 0x10, 0x42, 0x05, 0x01, 0x10, + 0x25, 0xa3, 0x00, 0x10, 0x9d, 0xea, 0x00, 0x10, 0x93, 0x68, 0x10, 0xb5, + 0x01, 0x3b, 0x93, 0x60, 0x00, 0x2b, 0x04, 0xda, 0x94, 0x69, 0xa3, 0x42, + 0x07, 0xdb, 0x0a, 0x29, 0x05, 0xd0, 0x13, 0x68, 0x58, 0x1c, 0x10, 0x60, + 0x19, 0x70, 0x08, 0x00, 0x10, 0xbd, 0x00, 0xf0, 0x97, 0xfb, 0x01, 0x00, + 0xf9, 0xe7, 0xf8, 0xb5, 0x1f, 0x00, 0x8b, 0x6e, 0x06, 0x00, 0x0d, 0x00, + 0x14, 0x00, 0x9b, 0x04, 0x0b, 0xd4, 0xd7, 0x19, 0xbc, 0x42, 0x0d, 0xd0, + 0x21, 0x78, 0x2a, 0x00, 0x30, 0x00, 0xff, 0xf7, 0xdb, 0xff, 0x01, 0x34, + 0x43, 0x1c, 0xf5, 0xd1, 0x0d, 0xe0, 0xbf, 0x08, 0xbf, 0x00, 0xd7, 0x19, + 0xbc, 0x42, 0x01, 0xd1, 0x00, 0x20, 0x08, 0xe0, 0x2a, 0x00, 0x30, 0x00, + 0x02, 0xcc, 0x00, 0xf0, 0xaf, 0xfc, 0x43, 0x1c, 0xf4, 0xd1, 0x01, 0x20, + 0x40, 0x42, 0xf8, 0xbd, 0xf0, 0xb5, 0x85, 0xb0, 0x01, 0x90, 0x90, 0x68, + 0x0d, 0x00, 0x14, 0x00, 0x00, 0x28, 0x02, 0xd1, 0x50, 0x60, 0x05, 0xb0, + 0xf0, 0xbd, 0x8b, 0x6e, 0x9b, 0x04, 0x21, 0xd5, 0x17, 0x68, 0x00, 0x26, + 0x3b, 0x68, 0x02, 0x93, 0x7b, 0x68, 0x00, 0x93, 0x9b, 0x08, 0x03, 0x93, + 0x03, 0x9b, 0x9e, 0x42, 0x0b, 0xdb, 0x03, 0x23, 0x00, 0x98, 0x08, 0x37, + 0x98, 0x43, 0xa3, 0x68, 0x18, 0x1a, 0xa0, 0x60, 0xed, 0xd1, 0x00, 0x23, + 0xa3, 0x60, 0x63, 0x60, 0xe3, 0xe7, 0x02, 0x99, 0xb3, 0x00, 0xc9, 0x58, + 0x2a, 0x00, 0x01, 0x98, 0x00, 0xf0, 0x7e, 0xfc, 0x43, 0x1c, 0xf2, 0xd0, + 0x01, 0x36, 0xe5, 0xe7, 0x01, 0x98, 0xfe, 0xf7, 0x67, 0xfb, 0xec, 0xe7, + 0xf0, 0xb5, 0xa1, 0xb0, 0x07, 0x00, 0x0e, 0x00, 0x1c, 0x00, 0x03, 0x92, + 0x00, 0x28, 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, 0x01, 0xd1, 0xfa, 0xf7, + 0x17, 0xfe, 0x9d, 0x4b, 0x9e, 0x42, 0x1d, 0xd1, 0x7e, 0x68, 0xb3, 0x6e, + 0xdb, 0x07, 0x06, 0xd4, 0xb3, 0x89, 0x9b, 0x05, 0x03, 0xd4, 0x30, 0x00, + 0x58, 0x30, 0x00, 0xf0, 0x72, 0xfd, 0xb3, 0x89, 0x1b, 0x07, 0x02, 0xd5, + 0x33, 0x69, 0x00, 0x2b, 0x1e, 0xd1, 0x31, 0x00, 0x38, 0x00, 0x00, 0xf0, + 0x9d, 0xfb, 0x00, 0x28, 0x18, 0xd0, 0xb3, 0x6e, 0xdb, 0x07, 0x0d, 0xd5, + 0x01, 0x20, 0x40, 0x42, 0x21, 0xb0, 0xf0, 0xbd, 0x8d, 0x4b, 0x9e, 0x42, + 0x01, 0xd1, 0xbe, 0x68, 0xdd, 0xe7, 0x8c, 0x4b, 0x9e, 0x42, 0xda, 0xd1, + 0xfe, 0x68, 0xd8, 0xe7, 0xb3, 0x89, 0x9b, 0x05, 0xee, 0xd4, 0x30, 0x00, + 0x58, 0x30, 0x00, 0xf0, 0x52, 0xfd, 0xe9, 0xe7, 0x00, 0x23, 0x08, 0xad, + 0x6b, 0x61, 0x20, 0x33, 0x6b, 0x76, 0x10, 0x33, 0xab, 0x76, 0x07, 0x94, + 0x03, 0x9c, 0x23, 0x78, 0x00, 0x2b, 0x01, 0xd0, 0x25, 0x2b, 0x4a, 0xd1, + 0x03, 0x9b, 0xe3, 0x1a, 0x05, 0x93, 0x03, 0x9b, 0x9c, 0x42, 0x0d, 0xd0, + 0x05, 0x9b, 0x31, 0x00, 0x38, 0x00, 0x03, 0x9a, 0xff, 0xf7, 0x4d, 0xff, + 0x43, 0x1c, 0x00, 0xd1, 0xd0, 0xe0, 0x6a, 0x69, 0x05, 0x9b, 0x94, 0x46, + 0x63, 0x44, 0x6b, 0x61, 0x23, 0x78, 0x00, 0x2b, 0x00, 0xd1, 0xc7, 0xe0, + 0x01, 0x22, 0x00, 0x23, 0x52, 0x42, 0x6a, 0x60, 0x04, 0xa9, 0x54, 0x32, + 0x52, 0x18, 0x01, 0x34, 0x2b, 0x60, 0xeb, 0x60, 0xab, 0x60, 0x13, 0x70, + 0xab, 0x65, 0x05, 0x22, 0x21, 0x78, 0x6c, 0x48, 0x00, 0xf0, 0xee, 0xfd, + 0x62, 0x1c, 0x00, 0x28, 0x1f, 0xd1, 0x29, 0x68, 0xcb, 0x06, 0x04, 0xd5, + 0x53, 0x23, 0x04, 0xa8, 0x1b, 0x18, 0x20, 0x20, 0x18, 0x70, 0x0b, 0x07, + 0x04, 0xd5, 0x53, 0x23, 0x04, 0xa8, 0x1b, 0x18, 0x2b, 0x20, 0x18, 0x70, + 0x23, 0x78, 0x2a, 0x2b, 0x16, 0xd0, 0x0a, 0x21, 0x22, 0x78, 0x60, 0x1c, + 0x30, 0x3a, 0x09, 0x2a, 0x18, 0xd8, 0xeb, 0x68, 0x04, 0x00, 0x4b, 0x43, + 0x9b, 0x18, 0xeb, 0x60, 0xf4, 0xe7, 0x01, 0x34, 0xad, 0xe7, 0x59, 0x4b, + 0x29, 0x68, 0xc0, 0x1a, 0x01, 0x23, 0x83, 0x40, 0x0b, 0x43, 0x14, 0x00, + 0x2b, 0x60, 0xce, 0xe7, 0x07, 0x9b, 0x18, 0x1d, 0x1b, 0x68, 0x07, 0x90, + 0x00, 0x2b, 0x5f, 0xdb, 0x0b, 0x93, 0x14, 0x00, 0x23, 0x78, 0x2e, 0x2b, + 0x0a, 0xd1, 0x63, 0x78, 0x2a, 0x2b, 0x60, 0xd1, 0x07, 0x9b, 0x02, 0x34, + 0x1a, 0x1d, 0x1b, 0x68, 0x07, 0x92, 0x00, 0x2b, 0x56, 0xdb, 0x09, 0x93, + 0x03, 0x22, 0x21, 0x78, 0x49, 0x48, 0x00, 0xf0, 0xa7, 0xfd, 0x00, 0x28, + 0x07, 0xd0, 0x47, 0x4b, 0x2a, 0x68, 0xc0, 0x1a, 0x40, 0x23, 0x83, 0x40, + 0x13, 0x43, 0x01, 0x34, 0x2b, 0x60, 0x80, 0x22, 0x2b, 0x68, 0x13, 0x42, + 0x08, 0xd0, 0x21, 0x78, 0x6c, 0x29, 0x05, 0xd1, 0x93, 0x43, 0x80, 0x22, + 0x12, 0x01, 0x13, 0x43, 0x01, 0x34, 0x2b, 0x60, 0x40, 0x22, 0x2b, 0x68, + 0x13, 0x42, 0x08, 0xd0, 0x21, 0x78, 0x68, 0x29, 0x05, 0xd1, 0x93, 0x43, + 0xc1, 0x32, 0xff, 0x32, 0x13, 0x43, 0x01, 0x34, 0x2b, 0x60, 0x23, 0x78, + 0x7a, 0x2b, 0x01, 0xd0, 0x74, 0x2b, 0x00, 0xd1, 0x01, 0x34, 0x23, 0x78, + 0x6a, 0x2b, 0x05, 0xd1, 0x80, 0x23, 0x2a, 0x68, 0x1b, 0x01, 0x13, 0x43, + 0x01, 0x34, 0x2b, 0x60, 0x21, 0x78, 0x63, 0x1c, 0x06, 0x22, 0x2e, 0x48, + 0x03, 0x93, 0x29, 0x76, 0x00, 0xf0, 0x6c, 0xfd, 0x00, 0x28, 0x41, 0xd0, + 0x2b, 0x4b, 0x00, 0x2b, 0x22, 0xd1, 0x07, 0x22, 0x07, 0x9b, 0x07, 0x33, + 0x93, 0x43, 0x08, 0x33, 0x07, 0x93, 0x6b, 0x69, 0x04, 0x9a, 0x9b, 0x18, + 0x6b, 0x61, 0x3d, 0xe7, 0x5b, 0x42, 0xeb, 0x60, 0x02, 0x23, 0x0b, 0x43, + 0x2b, 0x60, 0x9a, 0xe7, 0x01, 0x23, 0x5b, 0x42, 0xa5, 0xe7, 0x00, 0x23, + 0x0a, 0x21, 0x01, 0x34, 0x09, 0x93, 0x22, 0x78, 0x60, 0x1c, 0x30, 0x3a, + 0x09, 0x2a, 0x9d, 0xd8, 0x6b, 0x68, 0x04, 0x00, 0x4b, 0x43, 0x9b, 0x18, + 0x6b, 0x60, 0xf4, 0xe7, 0x07, 0xab, 0x00, 0x93, 0x32, 0x00, 0x29, 0x00, + 0x38, 0x00, 0x17, 0x4b, 0xfb, 0xf7, 0xaa, 0xf8, 0x04, 0x90, 0x04, 0x9b, + 0x01, 0x33, 0xd6, 0xd1, 0xb3, 0x6e, 0xdb, 0x07, 0x06, 0xd4, 0xb3, 0x89, + 0x9b, 0x05, 0x03, 0xd4, 0x30, 0x00, 0x58, 0x30, 0x00, 0xf0, 0x59, 0xfc, + 0xb3, 0x89, 0x5b, 0x06, 0x00, 0xd5, 0xed, 0xe6, 0x0d, 0x98, 0xed, 0xe6, + 0x07, 0xab, 0x00, 0x93, 0x32, 0x00, 0x29, 0x00, 0x38, 0x00, 0x09, 0x4b, + 0xfb, 0xf7, 0x4b, 0xfb, 0xe2, 0xe7, 0xc0, 0x46, 0x78, 0x01, 0x01, 0x10, + 0x58, 0x01, 0x01, 0x10, 0x38, 0x01, 0x01, 0x10, 0x38, 0x05, 0x01, 0x10, + 0x3e, 0x05, 0x01, 0x10, 0x42, 0x05, 0x01, 0x10, 0x25, 0xa3, 0x00, 0x10, + 0xcb, 0xee, 0x00, 0x10, 0x70, 0xb5, 0x0d, 0x00, 0x16, 0x00, 0x04, 0x00, + 0xf5, 0xf7, 0x24, 0xfb, 0x33, 0x00, 0x2a, 0x00, 0x21, 0x00, 0xff, 0xf7, + 0x9d, 0xfe, 0x70, 0xbd, 0x70, 0xb5, 0x04, 0x00, 0x08, 0x00, 0x11, 0x00, + 0x1a, 0x00, 0x00, 0x23, 0x05, 0x4d, 0x2b, 0x60, 0x00, 0xf0, 0x5a, 0xfc, + 0x43, 0x1c, 0x03, 0xd1, 0x2b, 0x68, 0x00, 0x2b, 0x00, 0xd0, 0x23, 0x60, + 0x70, 0xbd, 0xc0, 0x46, 0x20, 0x0e, 0x00, 0x20, 0xf0, 0xb5, 0x87, 0xb0, + 0x0c, 0x1e, 0x02, 0x90, 0x05, 0x92, 0x06, 0xd1, 0x11, 0x00, 0xfa, 0xf7, + 0x89, 0xfd, 0x07, 0x00, 0x38, 0x00, 0x07, 0xb0, 0xf0, 0xbd, 0x02, 0x98, + 0xfa, 0xf7, 0x92, 0xff, 0x05, 0x9b, 0x0b, 0x33, 0x16, 0x2b, 0x08, 0xd9, + 0x07, 0x22, 0x93, 0x43, 0x01, 0x93, 0x06, 0xd5, 0x0c, 0x23, 0x02, 0x9a, + 0x00, 0x27, 0x13, 0x60, 0xec, 0xe7, 0x10, 0x23, 0x01, 0x93, 0x01, 0x9b, + 0x05, 0x9a, 0x93, 0x42, 0xf4, 0xd3, 0x23, 0x00, 0x08, 0x3b, 0x5f, 0x68, + 0x04, 0x93, 0x3a, 0x00, 0x03, 0x23, 0x9a, 0x43, 0x01, 0x9b, 0x03, 0x92, + 0x93, 0x42, 0x00, 0xdc, 0x68, 0xe1, 0x04, 0x9b, 0xb7, 0x48, 0x9b, 0x18, + 0x82, 0x68, 0x94, 0x46, 0x5a, 0x68, 0x9c, 0x45, 0x06, 0xd0, 0x01, 0x25, + 0x11, 0x00, 0xa9, 0x43, 0x59, 0x18, 0x49, 0x68, 0x29, 0x42, 0x27, 0xd1, + 0x03, 0x21, 0x8a, 0x43, 0x03, 0x99, 0x8e, 0x18, 0x01, 0x99, 0x9c, 0x45, + 0x18, 0xd1, 0x10, 0x31, 0xb1, 0x42, 0x1f, 0xdc, 0x01, 0x99, 0x04, 0x9b, + 0x8c, 0x46, 0x63, 0x44, 0x83, 0x60, 0x1a, 0x00, 0x01, 0x23, 0x76, 0x1a, + 0x1e, 0x43, 0x56, 0x60, 0x22, 0x00, 0x08, 0x3a, 0x51, 0x68, 0x02, 0x98, + 0x0b, 0x40, 0x61, 0x46, 0x0b, 0x43, 0x53, 0x60, 0xfa, 0xf7, 0x4e, 0xff, + 0x27, 0x00, 0xab, 0xe7, 0xb1, 0x42, 0x07, 0xdc, 0xda, 0x68, 0x9b, 0x68, + 0xda, 0x60, 0x93, 0x60, 0x04, 0x9d, 0x7f, 0xe0, 0x00, 0x22, 0x13, 0x00, + 0xf9, 0x07, 0x00, 0xd5, 0xe2, 0xe0, 0x21, 0x00, 0x08, 0x39, 0x0d, 0x68, + 0x04, 0x99, 0x4d, 0x1b, 0x03, 0x21, 0x6f, 0x68, 0x8f, 0x43, 0x03, 0x99, + 0x7f, 0x18, 0x00, 0x2b, 0x00, 0xd1, 0xa0, 0xe0, 0xd6, 0x19, 0x9c, 0x45, + 0x49, 0xd1, 0x01, 0x9b, 0x10, 0x33, 0xb3, 0x42, 0x00, 0xdd, 0x98, 0xe0, + 0xaa, 0x68, 0xeb, 0x68, 0x2f, 0x00, 0xd3, 0x60, 0x9a, 0x60, 0x0a, 0x00, + 0x04, 0x3a, 0x08, 0x37, 0x24, 0x2a, 0x35, 0xd8, 0x3b, 0x00, 0x13, 0x2a, + 0x08, 0xd9, 0x23, 0x68, 0xab, 0x60, 0x63, 0x68, 0xeb, 0x60, 0x1b, 0x2a, + 0x1a, 0xd8, 0x2b, 0x00, 0x08, 0x34, 0x10, 0x33, 0x22, 0x68, 0x1a, 0x60, + 0x62, 0x68, 0x5a, 0x60, 0xa2, 0x68, 0x9a, 0x60, 0x01, 0x9b, 0xea, 0x18, + 0x80, 0x4b, 0x9a, 0x60, 0x01, 0x9b, 0xf6, 0x1a, 0x01, 0x23, 0x1e, 0x43, + 0x56, 0x60, 0x6a, 0x68, 0x13, 0x40, 0x01, 0x9a, 0x13, 0x43, 0x6b, 0x60, + 0x02, 0x98, 0xfa, 0xf7, 0xfd, 0xfe, 0x5b, 0xe7, 0xa3, 0x68, 0x2b, 0x61, + 0xe3, 0x68, 0x6b, 0x61, 0x24, 0x2a, 0x03, 0xd0, 0x2b, 0x00, 0x10, 0x34, + 0x18, 0x33, 0xdd, 0xe7, 0x23, 0x69, 0xab, 0x61, 0x2b, 0x00, 0x62, 0x69, + 0x20, 0x33, 0xea, 0x61, 0x18, 0x34, 0xd5, 0xe7, 0x21, 0x00, 0x38, 0x00, + 0x00, 0xf0, 0x7a, 0xfc, 0xd6, 0xe7, 0x01, 0x9a, 0xb2, 0x42, 0x50, 0xdc, + 0x28, 0x00, 0xda, 0x68, 0x9b, 0x68, 0x08, 0x30, 0xda, 0x60, 0x93, 0x60, + 0xaa, 0x68, 0xeb, 0x68, 0xd3, 0x60, 0x9a, 0x60, 0x03, 0x9a, 0x04, 0x3a, + 0x24, 0x2a, 0x3e, 0xd8, 0x13, 0x2a, 0x07, 0xd9, 0x23, 0x68, 0xab, 0x60, + 0x63, 0x68, 0xeb, 0x60, 0x1b, 0x2a, 0x24, 0xd8, 0x08, 0x34, 0x08, 0x30, + 0x23, 0x68, 0x03, 0x60, 0x63, 0x68, 0x43, 0x60, 0xa3, 0x68, 0x83, 0x60, + 0x01, 0x9b, 0x68, 0x68, 0xf4, 0x1a, 0x01, 0x23, 0xaa, 0x19, 0x18, 0x40, + 0x0f, 0x2c, 0x00, 0xd8, 0xaa, 0xe0, 0x01, 0x99, 0x01, 0x9e, 0x69, 0x18, + 0x30, 0x43, 0x1c, 0x43, 0x68, 0x60, 0x4c, 0x60, 0x50, 0x68, 0x08, 0x31, + 0x03, 0x43, 0x53, 0x60, 0x02, 0x98, 0xfe, 0xf7, 0x3f, 0xf8, 0x02, 0x98, + 0x08, 0x35, 0xfa, 0xf7, 0xa9, 0xfe, 0x2f, 0x00, 0x06, 0xe7, 0xa3, 0x68, + 0x2b, 0x61, 0xe3, 0x68, 0x6b, 0x61, 0x24, 0x2a, 0x03, 0xd0, 0x28, 0x00, + 0x10, 0x34, 0x18, 0x30, 0xd2, 0xe7, 0x28, 0x00, 0x23, 0x69, 0x20, 0x30, + 0xab, 0x61, 0x63, 0x69, 0x18, 0x34, 0xeb, 0x61, 0xca, 0xe7, 0x21, 0x00, + 0x00, 0xf0, 0x26, 0xfc, 0xcc, 0xe7, 0x01, 0x9b, 0xbb, 0x42, 0x31, 0xdc, + 0x28, 0x00, 0xaa, 0x68, 0xeb, 0x68, 0x08, 0x30, 0xd3, 0x60, 0x9a, 0x60, + 0x03, 0x9a, 0x04, 0x3a, 0x24, 0x2a, 0x23, 0xd8, 0x13, 0x2a, 0x07, 0xd9, + 0x23, 0x68, 0xab, 0x60, 0x63, 0x68, 0xeb, 0x60, 0x1b, 0x2a, 0x09, 0xd8, + 0x08, 0x34, 0x08, 0x30, 0x23, 0x68, 0x03, 0x60, 0x63, 0x68, 0x43, 0x60, + 0xa3, 0x68, 0x83, 0x60, 0x3e, 0x00, 0xad, 0xe7, 0xa3, 0x68, 0x2b, 0x61, + 0xe3, 0x68, 0x6b, 0x61, 0x24, 0x2a, 0x03, 0xd0, 0x28, 0x00, 0x10, 0x34, + 0x18, 0x30, 0xed, 0xe7, 0x28, 0x00, 0x23, 0x69, 0x20, 0x30, 0xab, 0x61, + 0x63, 0x69, 0x18, 0x34, 0xeb, 0x61, 0xe5, 0xe7, 0x21, 0x00, 0x00, 0xf0, + 0xf1, 0xfb, 0xe7, 0xe7, 0x05, 0x99, 0x02, 0x98, 0xfa, 0xf7, 0x40, 0xfc, + 0x07, 0x1e, 0x00, 0xd1, 0x54, 0xe7, 0x23, 0x00, 0x01, 0x22, 0x08, 0x3b, + 0x5b, 0x68, 0x93, 0x43, 0x04, 0x9a, 0xd3, 0x18, 0x02, 0x00, 0x08, 0x3a, + 0x93, 0x42, 0x05, 0xd1, 0x5e, 0x68, 0x03, 0x23, 0x9e, 0x43, 0x03, 0x9b, + 0xf6, 0x18, 0xfd, 0xe6, 0x03, 0x9a, 0x04, 0x3a, 0x24, 0x2a, 0x29, 0xd8, + 0x03, 0x00, 0x21, 0x00, 0x13, 0x2a, 0x08, 0xd9, 0x23, 0x68, 0x03, 0x60, + 0x63, 0x68, 0x43, 0x60, 0x1b, 0x2a, 0x0d, 0xd8, 0x03, 0x00, 0x08, 0x31, + 0x08, 0x33, 0x0a, 0x68, 0x1a, 0x60, 0x4a, 0x68, 0x5a, 0x60, 0x8a, 0x68, + 0x9a, 0x60, 0x21, 0x00, 0x02, 0x98, 0xfd, 0xf7, 0xbb, 0xff, 0x27, 0xe7, + 0xa3, 0x68, 0x83, 0x60, 0xe3, 0x68, 0xc3, 0x60, 0x24, 0x2a, 0x03, 0xd0, + 0x03, 0x00, 0x10, 0x31, 0x10, 0x33, 0xea, 0xe7, 0x23, 0x69, 0x18, 0x31, + 0x03, 0x61, 0x03, 0x00, 0x62, 0x69, 0x18, 0x33, 0x42, 0x61, 0xe2, 0xe7, + 0x21, 0x00, 0x00, 0xf0, 0xa7, 0xfb, 0xe4, 0xe7, 0x03, 0x9e, 0xc9, 0xe6, + 0x06, 0x43, 0x6e, 0x60, 0x51, 0x68, 0x0b, 0x43, 0x53, 0x60, 0x5c, 0xe7, + 0x98, 0x06, 0x00, 0x20, 0x00, 0x20, 0x01, 0x49, 0x70, 0x47, 0xc0, 0x46, + 0x00, 0x00, 0xf8, 0x7f, 0x02, 0x78, 0x0b, 0x78, 0x00, 0x2a, 0x03, 0xd0, + 0x01, 0x30, 0x01, 0x31, 0x9a, 0x42, 0xf7, 0xd0, 0xd0, 0x1a, 0x70, 0x47, + 0x30, 0xb5, 0x05, 0x00, 0x10, 0x1e, 0x08, 0xd0, 0x00, 0x24, 0x01, 0x3a, + 0x2b, 0x5d, 0x08, 0x5d, 0x83, 0x42, 0x01, 0xd1, 0x94, 0x42, 0x01, 0xd1, + 0x18, 0x1a, 0x30, 0xbd, 0x01, 0x34, 0x00, 0x2b, 0xf4, 0xd1, 0xf9, 0xe7, + 0xf8, 0xb5, 0x05, 0x00, 0x0e, 0x00, 0x14, 0x00, 0x00, 0x28, 0x04, 0xd0, + 0x83, 0x69, 0x00, 0x2b, 0x01, 0xd1, 0xfa, 0xf7, 0xdd, 0xfa, 0x29, 0x4b, + 0x9c, 0x42, 0x34, 0xd1, 0x6c, 0x68, 0xa3, 0x69, 0xa3, 0x60, 0xa3, 0x89, + 0x1b, 0x07, 0x38, 0xd5, 0x23, 0x69, 0x00, 0x2b, 0x35, 0xd0, 0x0c, 0x23, + 0xe2, 0x5e, 0x80, 0x23, 0x9b, 0x01, 0xf7, 0xb2, 0xf6, 0xb2, 0x1a, 0x42, + 0x36, 0xd0, 0x23, 0x68, 0x22, 0x69, 0x98, 0x1a, 0x63, 0x69, 0x83, 0x42, + 0x05, 0xdc, 0x21, 0x00, 0x28, 0x00, 0xfd, 0xf7, 0xab, 0xfe, 0x00, 0x28, + 0x27, 0xd1, 0xa3, 0x68, 0x01, 0x30, 0x01, 0x3b, 0xa3, 0x60, 0x23, 0x68, + 0x5a, 0x1c, 0x22, 0x60, 0x1f, 0x70, 0x63, 0x69, 0x83, 0x42, 0x04, 0xd0, + 0xa3, 0x89, 0xdb, 0x07, 0x07, 0xd5, 0x0a, 0x2e, 0x05, 0xd1, 0x21, 0x00, + 0x28, 0x00, 0xfd, 0xf7, 0x95, 0xfe, 0x00, 0x28, 0x11, 0xd1, 0x30, 0x00, + 0xf8, 0xbd, 0x0e, 0x4b, 0x9c, 0x42, 0x01, 0xd1, 0xac, 0x68, 0xc6, 0xe7, + 0x0c, 0x4b, 0x9c, 0x42, 0xc3, 0xd1, 0xec, 0x68, 0xc1, 0xe7, 0x21, 0x00, + 0x28, 0x00, 0x00, 0xf0, 0x35, 0xf8, 0x00, 0x28, 0xc3, 0xd0, 0x01, 0x26, + 0x76, 0x42, 0xea, 0xe7, 0x13, 0x43, 0xa3, 0x81, 0xa2, 0x6e, 0x05, 0x4b, + 0x13, 0x40, 0xa3, 0x66, 0xc1, 0xe7, 0xc0, 0x46, 0x78, 0x01, 0x01, 0x10, + 0x58, 0x01, 0x01, 0x10, 0x38, 0x01, 0x01, 0x10, 0xff, 0xdf, 0xff, 0xff, + 0x70, 0xb5, 0x0d, 0x00, 0x04, 0x00, 0xf5, 0xf7, 0xdb, 0xf8, 0x2a, 0x00, + 0x21, 0x00, 0xff, 0xf7, 0x91, 0xff, 0x70, 0xbd, 0x10, 0xb5, 0x02, 0x4c, + 0xe0, 0x34, 0x24, 0x68, 0xa0, 0x47, 0x10, 0xbd, 0xa4, 0x0a, 0x00, 0x20, + 0x03, 0x00, 0x08, 0x1e, 0x05, 0xd0, 0xff, 0x2a, 0x04, 0xd9, 0x8a, 0x22, + 0x01, 0x20, 0x1a, 0x60, 0x40, 0x42, 0x70, 0x47, 0x01, 0x20, 0x0a, 0x70, + 0xfb, 0xe7, 0xc0, 0x46, 0x70, 0xb5, 0x06, 0x00, 0x0c, 0x00, 0xf5, 0xf7, + 0xbb, 0xf8, 0x05, 0x1e, 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, 0x01, 0xd1, + 0xfa, 0xf7, 0x56, 0xfa, 0x31, 0x4b, 0x9c, 0x42, 0x0f, 0xd1, 0x6c, 0x68, + 0x0c, 0x23, 0xe2, 0x5e, 0x93, 0xb2, 0x11, 0x07, 0x2d, 0xd4, 0xd9, 0x06, + 0x11, 0xd4, 0x09, 0x23, 0x01, 0x20, 0x33, 0x60, 0x37, 0x33, 0x13, 0x43, + 0xa3, 0x81, 0x40, 0x42, 0x70, 0xbd, 0x29, 0x4b, 0x9c, 0x42, 0x01, 0xd1, + 0xac, 0x68, 0xeb, 0xe7, 0x27, 0x4b, 0x9c, 0x42, 0xe8, 0xd1, 0xec, 0x68, + 0xe6, 0xe7, 0x5b, 0x07, 0x13, 0xd5, 0x61, 0x6b, 0x00, 0x29, 0x08, 0xd0, + 0x23, 0x00, 0x44, 0x33, 0x99, 0x42, 0x02, 0xd0, 0x30, 0x00, 0xfd, 0xf7, + 0xbd, 0xfe, 0x00, 0x23, 0x63, 0x63, 0x24, 0x22, 0xa3, 0x89, 0x93, 0x43, + 0xa3, 0x81, 0x00, 0x23, 0x63, 0x60, 0x23, 0x69, 0x23, 0x60, 0x08, 0x23, + 0xa2, 0x89, 0x13, 0x43, 0xa3, 0x81, 0x23, 0x69, 0x00, 0x2b, 0x0b, 0xd1, + 0xa0, 0x21, 0x80, 0x22, 0xa3, 0x89, 0x89, 0x00, 0x92, 0x00, 0x0b, 0x40, + 0x93, 0x42, 0x03, 0xd0, 0x21, 0x00, 0x30, 0x00, 0x00, 0xf0, 0xe6, 0xf8, + 0x0c, 0x22, 0xa3, 0x5e, 0x01, 0x20, 0x1a, 0x00, 0x99, 0xb2, 0x02, 0x40, + 0x03, 0x42, 0x0f, 0xd0, 0x00, 0x22, 0xa2, 0x60, 0x62, 0x69, 0x52, 0x42, + 0xa2, 0x61, 0x00, 0x20, 0x22, 0x69, 0x82, 0x42, 0xba, 0xd1, 0x0a, 0x06, + 0xb8, 0xd5, 0x40, 0x22, 0x13, 0x43, 0xa3, 0x81, 0x01, 0x38, 0xb3, 0xe7, + 0x88, 0x07, 0x00, 0xd4, 0x62, 0x69, 0xa2, 0x60, 0xef, 0xe7, 0xc0, 0x46, + 0x78, 0x01, 0x01, 0x10, 0x58, 0x01, 0x01, 0x10, 0x38, 0x01, 0x01, 0x10, + 0xf0, 0xb5, 0x85, 0xb0, 0x0e, 0x00, 0x15, 0x00, 0x01, 0x90, 0xfe, 0xf7, + 0x23, 0xfc, 0x04, 0x00, 0x01, 0x28, 0x19, 0xd1, 0x73, 0x1e, 0xfe, 0x2b, + 0x16, 0xd8, 0x02, 0xab, 0x1e, 0x71, 0x00, 0x27, 0xa7, 0x42, 0x20, 0xd0, + 0x03, 0xab, 0xd9, 0x5d, 0xab, 0x68, 0x01, 0x3b, 0xab, 0x60, 0x00, 0x2b, + 0x04, 0xda, 0xaa, 0x69, 0x93, 0x42, 0x19, 0xdb, 0x0a, 0x29, 0x17, 0xd0, + 0x2b, 0x68, 0x5a, 0x1c, 0x2a, 0x60, 0x19, 0x70, 0x01, 0x37, 0xeb, 0xe7, + 0x2b, 0x00, 0x32, 0x00, 0x01, 0x98, 0x60, 0x33, 0x03, 0xa9, 0x00, 0xf0, + 0xdd, 0xf8, 0x04, 0x00, 0x43, 0x1c, 0xe0, 0xd1, 0x40, 0x23, 0x06, 0x00, + 0xaa, 0x89, 0x13, 0x43, 0xab, 0x81, 0x30, 0x00, 0x05, 0xb0, 0xf0, 0xbd, + 0x2a, 0x00, 0x01, 0x98, 0xff, 0xf7, 0xca, 0xfe, 0x43, 0x1c, 0xe5, 0xd1, + 0x06, 0x00, 0xf4, 0xe7, 0x93, 0x6e, 0x70, 0xb5, 0x05, 0x00, 0x0e, 0x00, + 0x14, 0x00, 0xdb, 0x07, 0x06, 0xd4, 0x93, 0x89, 0x9b, 0x05, 0x03, 0xd4, + 0x10, 0x00, 0x58, 0x30, 0x00, 0xf0, 0x09, 0xf9, 0x0c, 0x23, 0xe2, 0x5e, + 0x80, 0x23, 0x9b, 0x01, 0x1a, 0x42, 0x04, 0xd1, 0x1a, 0x43, 0xa2, 0x81, + 0xa2, 0x6e, 0x13, 0x43, 0xa3, 0x66, 0x28, 0x00, 0x22, 0x00, 0x31, 0x00, + 0xff, 0xf7, 0xa4, 0xff, 0xa3, 0x6e, 0x05, 0x00, 0xdb, 0x07, 0x06, 0xd4, + 0xa3, 0x89, 0x9b, 0x05, 0x03, 0xd4, 0x20, 0x00, 0x58, 0x30, 0x00, 0xf0, + 0xf2, 0xf8, 0x28, 0x00, 0x70, 0xbd, 0x70, 0xb5, 0x06, 0x00, 0x0d, 0x00, + 0xf4, 0xf7, 0xdc, 0xff, 0x04, 0x1e, 0x04, 0xd0, 0x83, 0x69, 0x00, 0x2b, + 0x01, 0xd1, 0xfa, 0xf7, 0x77, 0xf9, 0x0a, 0x4b, 0x9d, 0x42, 0x06, 0xd1, + 0x65, 0x68, 0x2a, 0x00, 0x31, 0x00, 0x20, 0x00, 0xff, 0xf7, 0xc0, 0xff, + 0x70, 0xbd, 0x06, 0x4b, 0x9d, 0x42, 0x01, 0xd1, 0xa5, 0x68, 0xf4, 0xe7, + 0x04, 0x4b, 0x9d, 0x42, 0xf1, 0xd1, 0xe5, 0x68, 0xef, 0xe7, 0xc0, 0x46, + 0x78, 0x01, 0x01, 0x10, 0x58, 0x01, 0x01, 0x10, 0x38, 0x01, 0x01, 0x10, + 0x70, 0xb5, 0x0e, 0x00, 0x1d, 0x00, 0x0e, 0x23, 0xc9, 0x5e, 0x14, 0x00, + 0x96, 0xb0, 0x00, 0x29, 0x0c, 0xda, 0x0c, 0x23, 0xf1, 0x5e, 0x80, 0x22, + 0x00, 0x23, 0x08, 0x00, 0x2b, 0x60, 0x10, 0x40, 0x11, 0x42, 0x17, 0xd1, + 0x80, 0x23, 0xdb, 0x00, 0x23, 0x60, 0x16, 0xe0, 0x6a, 0x46, 0x00, 0xf0, + 0x83, 0xf8, 0x00, 0x28, 0xed, 0xdb, 0xf0, 0x23, 0x01, 0x99, 0x1b, 0x02, + 0x19, 0x40, 0x08, 0x4b, 0x80, 0x20, 0xc9, 0x18, 0x4b, 0x42, 0x59, 0x41, + 0x80, 0x23, 0xdb, 0x00, 0x29, 0x60, 0x00, 0x01, 0x23, 0x60, 0x02, 0xe0, + 0x40, 0x22, 0x18, 0x00, 0x22, 0x60, 0x16, 0xb0, 0x70, 0xbd, 0xc0, 0x46, + 0x00, 0xe0, 0xff, 0xff, 0xf0, 0xb5, 0x02, 0x26, 0x8b, 0x89, 0x05, 0x00, + 0x0c, 0x00, 0x85, 0xb0, 0x33, 0x42, 0x07, 0xd0, 0x23, 0x00, 0x47, 0x33, + 0x23, 0x60, 0x23, 0x61, 0x01, 0x23, 0x63, 0x61, 0x05, 0xb0, 0xf0, 0xbd, + 0x03, 0xab, 0x02, 0xaa, 0xff, 0xf7, 0xba, 0xff, 0x02, 0x9f, 0x01, 0x90, + 0x39, 0x00, 0x28, 0x00, 0xfa, 0xf7, 0xf6, 0xf9, 0x00, 0x28, 0x08, 0xd1, + 0x0c, 0x22, 0xa3, 0x5e, 0x9a, 0x05, 0xed, 0xd4, 0x03, 0x22, 0x93, 0x43, + 0x1e, 0x43, 0xa6, 0x81, 0xe2, 0xe7, 0x0f, 0x4b, 0xab, 0x62, 0x80, 0x23, + 0xa2, 0x89, 0x20, 0x60, 0x13, 0x43, 0xa3, 0x81, 0x03, 0x9b, 0x20, 0x61, + 0x67, 0x61, 0x00, 0x2b, 0x0d, 0xd0, 0x28, 0x00, 0x0e, 0x23, 0xe1, 0x5e, + 0x00, 0xf0, 0x46, 0xf8, 0x00, 0x28, 0x06, 0xd0, 0x03, 0x22, 0xa3, 0x89, + 0x93, 0x43, 0x1a, 0x00, 0x01, 0x23, 0x13, 0x43, 0xa3, 0x81, 0xa0, 0x89, + 0x01, 0x9b, 0x18, 0x43, 0xa0, 0x81, 0xc9, 0xe7, 0x09, 0x9b, 0x00, 0x10, + 0x7f, 0xb5, 0x1d, 0x00, 0x09, 0x4b, 0x04, 0x00, 0xe0, 0x33, 0x1e, 0x68, + 0x2b, 0x00, 0x00, 0x29, 0x01, 0xd1, 0x0a, 0x00, 0x01, 0xa9, 0x20, 0x00, + 0xb0, 0x47, 0x43, 0x1c, 0x03, 0xd1, 0x00, 0x23, 0x2b, 0x60, 0x8a, 0x33, + 0x23, 0x60, 0x04, 0xb0, 0x70, 0xbd, 0xc0, 0x46, 0xa4, 0x0a, 0x00, 0x20, + 0x70, 0xb5, 0x0d, 0x00, 0x16, 0x00, 0x04, 0x00, 0xf4, 0xf7, 0x24, 0xff, + 0x33, 0x00, 0x2a, 0x00, 0x21, 0x00, 0xff, 0xf7, 0xdd, 0xff, 0x70, 0xbd, + 0x00, 0x23, 0x70, 0xb5, 0x06, 0x4d, 0x04, 0x00, 0x08, 0x00, 0x11, 0x00, + 0x2b, 0x60, 0x00, 0xf0, 0x33, 0xf8, 0x43, 0x1c, 0x03, 0xd1, 0x2b, 0x68, + 0x00, 0x2b, 0x00, 0xd0, 0x23, 0x60, 0x70, 0xbd, 0x20, 0x0e, 0x00, 0x20, + 0x00, 0x23, 0x70, 0xb5, 0x06, 0x4d, 0x04, 0x00, 0x08, 0x00, 0x2b, 0x60, + 0x00, 0xf0, 0x32, 0xf8, 0x43, 0x1c, 0x03, 0xd1, 0x2b, 0x68, 0x00, 0x2b, + 0x00, 0xd0, 0x23, 0x60, 0x70, 0xbd, 0xc0, 0x46, 0x20, 0x0e, 0x00, 0x20, + 0x10, 0xb5, 0xf6, 0xf7, 0x52, 0xfb, 0x10, 0xbd, 0x70, 0x47, 0x10, 0xb5, + 0x00, 0xf0, 0xee, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0xf0, 0x12, 0xf9, + 0x10, 0xbd, 0x00, 0x20, 0x70, 0x47, 0x00, 0x00, 0x58, 0x22, 0x01, 0x20, + 0x01, 0x4b, 0x40, 0x42, 0x1a, 0x60, 0x70, 0x47, 0x20, 0x0e, 0x00, 0x20, + 0x58, 0x22, 0x01, 0x20, 0x01, 0x4b, 0x40, 0x42, 0x1a, 0x60, 0x70, 0x47, + 0x20, 0x0e, 0x00, 0x20, 0x58, 0x22, 0x01, 0x20, 0x01, 0x4b, 0x40, 0x42, + 0x1a, 0x60, 0x70, 0x47, 0x20, 0x0e, 0x00, 0x20, 0x58, 0x22, 0x02, 0x4b, + 0x00, 0x20, 0x1a, 0x60, 0x70, 0x47, 0xc0, 0x46, 0x20, 0x0e, 0x00, 0x20, + 0x58, 0x22, 0x01, 0x20, 0x01, 0x4b, 0x40, 0x42, 0x1a, 0x60, 0x70, 0x47, + 0x20, 0x0e, 0x00, 0x20, 0x58, 0x22, 0x01, 0x20, 0x01, 0x4b, 0x40, 0x42, + 0x1a, 0x60, 0x70, 0x47, 0x20, 0x0e, 0x00, 0x20, 0x01, 0x20, 0x40, 0x42, + 0x70, 0x47, 0x00, 0x00, 0x07, 0xb5, 0x48, 0x40, 0x41, 0x40, 0x48, 0x40, + 0x01, 0xe0, 0xc0, 0x46, 0x07, 0xb5, 0x42, 0x00, 0x12, 0x0e, 0x03, 0xd0, + 0xff, 0x2a, 0x03, 0xd1, 0x42, 0x02, 0x18, 0xd8, 0xc0, 0x0d, 0xc0, 0x05, + 0x4a, 0x00, 0x12, 0x0e, 0x03, 0xd0, 0xff, 0x2a, 0x03, 0xd1, 0x4a, 0x02, + 0x0f, 0xd8, 0xc9, 0x0d, 0xc9, 0x05, 0x01, 0x22, 0x41, 0x40, 0x05, 0xd4, + 0x41, 0x40, 0x01, 0xd5, 0x81, 0x42, 0x07, 0xbd, 0x88, 0x42, 0x07, 0xbd, + 0x01, 0x43, 0x49, 0x18, 0x01, 0xd0, 0xc0, 0x43, 0x00, 0x18, 0x07, 0xbd, + 0x00, 0xb5, 0xff, 0xf7, 0xdb, 0xff, 0x01, 0xd9, 0x00, 0x20, 0x00, 0xbd, + 0x01, 0x20, 0x00, 0xbd, 0x01, 0x23, 0x1b, 0x06, 0x42, 0x00, 0xd2, 0x18, + 0x04, 0xd8, 0x4a, 0x00, 0xd2, 0x18, 0x01, 0xd8, 0x00, 0x20, 0x70, 0x47, + 0x01, 0x20, 0x70, 0x47, 0x13, 0x23, 0x10, 0xb5, 0x10, 0x48, 0x1c, 0x78, + 0xf6, 0xf7, 0x10, 0xfb, 0x01, 0x00, 0x01, 0x2c, 0x13, 0xd1, 0x0e, 0x4c, + 0x54, 0x22, 0x20, 0x00, 0xf7, 0xf7, 0xaa, 0xfc, 0x15, 0x23, 0x0c, 0x4a, + 0x99, 0x00, 0x01, 0x33, 0x62, 0x50, 0x20, 0x2b, 0xfa, 0xd1, 0x22, 0x62, + 0xe2, 0x61, 0x09, 0x48, 0xf6, 0xf7, 0xf4, 0xfa, 0x08, 0x4b, 0x18, 0x60, + 0x10, 0xbd, 0x01, 0x2c, 0xf7, 0xdd, 0x80, 0x22, 0x02, 0x48, 0xf7, 0xf7, + 0x95, 0xfc, 0xf2, 0xe7, 0x53, 0x46, 0x00, 0x00, 0x80, 0x19, 0x00, 0x20, + 0xe9, 0xfb, 0x00, 0x10, 0x4c, 0x33, 0x00, 0x00, 0x7c, 0x19, 0x00, 0x20, + 0x07, 0xb5, 0x60, 0x46, 0x01, 0x88, 0x0a, 0x0a, 0x02, 0x30, 0xdf, 0x2a, + 0xfa, 0xd1, 0xc9, 0xb2, 0x82, 0x08, 0x04, 0xd3, 0x02, 0x88, 0x40, 0x88, + 0x00, 0x04, 0x10, 0x43, 0x00, 0xe0, 0x00, 0x68, 0x01, 0x4a, 0x50, 0x50, + 0x03, 0x90, 0x07, 0xbd, 0x80, 0x19, 0x00, 0x20, 0xf8, 0xb5, 0xc0, 0x46, + 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, + 0x3d, 0x03, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, + 0x60, 0x47, 0x00, 0xbf, 0x6d, 0x02, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, + 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, 0x59, 0x04, 0x00, 0x20, + 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, + 0x07, 0x04, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, + 0x60, 0x47, 0x00, 0xbf, 0x45, 0x04, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, + 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, 0x59, 0x04, 0x00, 0x20, + 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, + 0x47, 0x01, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, + 0x60, 0x47, 0x00, 0xbf, 0x97, 0x01, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, + 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, 0x31, 0x02, 0x00, 0x20, + 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, + 0x31, 0x04, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, + 0x60, 0x47, 0x00, 0xbf, 0x1d, 0x04, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, + 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, 0x95, 0x02, 0x00, 0x20, + 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, + 0x05, 0x01, 0x00, 0x20, 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, + 0x60, 0x47, 0x00, 0xbf, 0xe1, 0x03, 0x00, 0x20, 0x25, 0x39, 0x75, 0x3a, + 0x20, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x0d, 0x0a, 0x00, 0x25, 0x39, 0x75, + 0x3a, 0x20, 0x42, 0x4c, 0x49, 0x4e, 0x4b, 0x0d, 0x0a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x42, 0x00, 0x10, + 0x5d, 0x44, 0x00, 0x10, 0xf9, 0x43, 0x00, 0x10, 0x2d, 0x44, 0x00, 0x10, + 0xc5, 0x43, 0x00, 0x10, 0x69, 0x43, 0x00, 0x10, 0x25, 0x43, 0x00, 0x10, + 0x8b, 0x42, 0x00, 0x10, 0x81, 0x42, 0x00, 0x10, 0x97, 0x42, 0x00, 0x10, + 0x35, 0x45, 0x00, 0x10, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x63, + 0x6c, 0x6f, 0x63, 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x25, 0x75, 0x20, 0x6b, + 0x48, 0x7a, 0x20, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x62, 0x65, + 0x20, 0x65, 0x78, 0x61, 0x63, 0x74, 0x6c, 0x79, 0x20, 0x61, 0x63, 0x68, + 0x69, 0x65, 0x76, 0x65, 0x64, 0x00, 0x80, 0xfd, 0x00, 0x10, 0x02, 0xff, + 0x40, 0x00, 0x80, 0x00, 0x63, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x20, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x20, 0x73, 0x74, 0x64, 0x3a, 0x3a, 0x64, + 0x65, 0x71, 0x75, 0x65, 0x20, 0x6c, 0x61, 0x72, 0x67, 0x65, 0x72, 0x20, + 0x74, 0x68, 0x61, 0x6e, 0x20, 0x6d, 0x61, 0x78, 0x5f, 0x73, 0x69, 0x7a, + 0x65, 0x28, 0x29, 0x00, 0x75, 0x73, 0x5f, 0x73, 0x69, 0x6e, 0x63, 0x65, + 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x20, 0x3c, 0x3d, 0x20, 0x49, 0x4e, 0x54, + 0x36, 0x34, 0x5f, 0x4d, 0x41, 0x58, 0x00, 0x76, 0x6f, 0x69, 0x64, 0x20, + 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x5f, 0x75, 0x73, 0x5f, 0x73, 0x69, + 0x6e, 0x63, 0x65, 0x5f, 0x62, 0x6f, 0x6f, 0x74, 0x28, 0x61, 0x62, 0x73, + 0x6f, 0x6c, 0x75, 0x74, 0x65, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x5f, 0x74, + 0x2a, 0x2c, 0x20, 0x75, 0x69, 0x6e, 0x74, 0x36, 0x34, 0x5f, 0x74, 0x29, + 0x00, 0x2f, 0x68, 0x6f, 0x6d, 0x65, 0x2f, 0x65, 0x61, 0x72, 0x6c, 0x65, + 0x2f, 0x41, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x2f, 0x68, 0x61, 0x72, + 0x64, 0x77, 0x61, 0x72, 0x65, 0x2f, 0x70, 0x69, 0x63, 0x6f, 0x2f, 0x72, + 0x70, 0x32, 0x30, 0x34, 0x30, 0x2f, 0x2f, 0x70, 0x69, 0x63, 0x6f, 0x2d, + 0x73, 0x64, 0x6b, 0x2f, 0x73, 0x72, 0x63, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2f, 0x70, 0x69, 0x63, 0x6f, 0x5f, 0x62, 0x61, 0x73, 0x65, + 0x2f, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x2f, 0x70, 0x69, 0x63, + 0x6f, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x68, 0x00, 0x52, 0x61, + 0x73, 0x70, 0x62, 0x65, 0x72, 0x72, 0x79, 0x20, 0x50, 0x69, 0x00, 0x50, + 0x69, 0x63, 0x6f, 0x41, 0x72, 0x64, 0x75, 0x69, 0x6e, 0x6f, 0x00, 0x42, + 0x6f, 0x61, 0x72, 0x64, 0x20, 0x43, 0x44, 0x43, 0x00, 0x05, 0x01, 0x09, + 0x02, 0xa1, 0x01, 0x85, 0x01, 0x09, 0x01, 0xa1, 0x00, 0x05, 0x09, 0x19, + 0x01, 0x29, 0x05, 0x15, 0x00, 0x25, 0x01, 0x95, 0x05, 0x75, 0x01, 0x81, + 0x02, 0x95, 0x01, 0x75, 0x03, 0x81, 0x01, 0x05, 0x01, 0x09, 0x30, 0x09, + 0x31, 0x15, 0x81, 0x25, 0x7f, 0x95, 0x02, 0x75, 0x08, 0x81, 0x06, 0x09, + 0x38, 0x15, 0x81, 0x25, 0x7f, 0x95, 0x01, 0x75, 0x08, 0x81, 0x06, 0x05, + 0x0c, 0x0a, 0x38, 0x02, 0x15, 0x81, 0x25, 0x7f, 0x95, 0x01, 0x75, 0x08, + 0x81, 0x06, 0xc0, 0xc0, 0x05, 0x01, 0x09, 0x06, 0xa1, 0x01, 0x85, 0x01, + 0x05, 0x07, 0x19, 0xe0, 0x29, 0xe7, 0x15, 0x00, 0x25, 0x01, 0x95, 0x08, + 0x75, 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x08, 0x81, 0x01, 0x05, 0x08, + 0x19, 0x01, 0x29, 0x05, 0x95, 0x05, 0x75, 0x01, 0x91, 0x02, 0x95, 0x01, + 0x75, 0x03, 0x91, 0x01, 0x05, 0x07, 0x19, 0x00, 0x2a, 0xff, 0x00, 0x15, + 0x00, 0x26, 0xff, 0x00, 0x95, 0x06, 0x75, 0x08, 0x81, 0x00, 0xc0, 0x05, + 0x01, 0x09, 0x02, 0xa1, 0x01, 0x85, 0x02, 0x09, 0x01, 0xa1, 0x00, 0x05, + 0x09, 0x19, 0x01, 0x29, 0x05, 0x15, 0x00, 0x25, 0x01, 0x95, 0x05, 0x75, + 0x01, 0x81, 0x02, 0x95, 0x01, 0x75, 0x03, 0x81, 0x01, 0x05, 0x01, 0x09, + 0x30, 0x09, 0x31, 0x15, 0x81, 0x25, 0x7f, 0x95, 0x02, 0x75, 0x08, 0x81, + 0x06, 0x09, 0x38, 0x15, 0x81, 0x25, 0x7f, 0x95, 0x01, 0x75, 0x08, 0x81, + 0x06, 0x05, 0x0c, 0x0a, 0x38, 0x02, 0x15, 0x81, 0x25, 0x7f, 0x95, 0x01, + 0x75, 0x08, 0x81, 0x06, 0xc0, 0xc0, 0x08, 0x0b, 0x00, 0x02, 0x02, 0x02, + 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x01, 0x02, 0x02, 0x00, 0x04, 0x05, + 0x24, 0x00, 0x20, 0x01, 0x05, 0x24, 0x01, 0x00, 0x01, 0x04, 0x24, 0x02, + 0x02, 0x05, 0x24, 0x06, 0x00, 0x01, 0x07, 0x05, 0x81, 0x03, 0x08, 0x00, + 0x10, 0x09, 0x04, 0x01, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x07, 0x05, + 0x02, 0x02, 0x40, 0x00, 0x00, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x00, + 0x11, 0xfd, 0x00, 0x10, 0x62, 0xfe, 0x00, 0x10, 0x6f, 0xfe, 0x00, 0x10, + 0xbd, 0x1a, 0x00, 0x20, 0x7b, 0xfe, 0x00, 0x10, 0x4e, 0x6f, 0x20, 0x73, + 0x70, 0x69, 0x6e, 0x6c, 0x6f, 0x63, 0x6b, 0x73, 0x20, 0x61, 0x72, 0x65, + 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x00, 0x4e, + 0x6f, 0x20, 0x75, 0x73, 0x65, 0x72, 0x20, 0x49, 0x52, 0x51, 0x73, 0x20, + 0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, + 0x65, 0x00, 0x48, 0x61, 0x72, 0x64, 0x77, 0x61, 0x72, 0x65, 0x20, 0x61, + 0x6c, 0x61, 0x72, 0x6d, 0x20, 0x25, 0x64, 0x20, 0x61, 0x6c, 0x72, 0x65, + 0x61, 0x64, 0x79, 0x20, 0x63, 0x6c, 0x61, 0x69, 0x6d, 0x65, 0x64, 0x00, + 0x4e, 0x6f, 0x20, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x20, 0x73, + 0x70, 0x61, 0x63, 0x65, 0x00, 0x4e, 0x6f, 0x20, 0x50, 0x49, 0x4f, 0x20, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x20, 0x6d, 0x61, 0x63, 0x68, 0x69, 0x6e, + 0x65, 0x73, 0x20, 0x61, 0x72, 0x65, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, + 0x61, 0x62, 0x6c, 0x65, 0x00, 0x2c, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x00, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, + 0x69, 0x6f, 0x6e, 0x20, 0x22, 0x25, 0x73, 0x22, 0x20, 0x66, 0x61, 0x69, + 0x6c, 0x65, 0x64, 0x3a, 0x20, 0x66, 0x69, 0x6c, 0x65, 0x20, 0x22, 0x25, + 0x73, 0x22, 0x2c, 0x20, 0x6c, 0x69, 0x6e, 0x65, 0x20, 0x25, 0x64, 0x25, + 0x73, 0x25, 0x73, 0x0a, 0x00, 0x0a, 0x2a, 0x2a, 0x2a, 0x20, 0x50, 0x41, + 0x4e, 0x49, 0x43, 0x20, 0x2a, 0x2a, 0x2a, 0x0a, 0x00, 0x48, 0x61, 0x72, + 0x64, 0x20, 0x61, 0x73, 0x73, 0x65, 0x72, 0x74, 0x00, 0x00, 0x00, 0x00, + 0x91, 0x83, 0x00, 0x10, 0x0d, 0x84, 0x00, 0x10, 0x3d, 0x84, 0x00, 0x10, + 0xe1, 0x84, 0x00, 0x10, 0xb9, 0x85, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xb1, 0x86, 0x00, 0x10, 0x9d, 0x86, 0x00, 0x10, 0xbd, 0x86, 0x00, 0x10, + 0x71, 0x87, 0x00, 0x10, 0x55, 0x89, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x55, 0x6e, 0x68, 0x61, 0x6e, 0x64, 0x6c, 0x65, 0x64, 0x20, 0x49, 0x52, + 0x51, 0x20, 0x30, 0x78, 0x25, 0x78, 0x0a, 0x00, 0x65, 0x70, 0x20, 0x25, + 0x64, 0x20, 0x25, 0x73, 0x20, 0x77, 0x61, 0x73, 0x20, 0x61, 0x6c, 0x72, + 0x65, 0x61, 0x64, 0x79, 0x20, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x00, 0x43, 0x61, 0x6e, 0x27, 0x74, 0x20, 0x63, 0x6f, 0x6e, + 0x74, 0x69, 0x6e, 0x75, 0x65, 0x20, 0x78, 0x66, 0x65, 0x72, 0x20, 0x6f, + 0x6e, 0x20, 0x69, 0x6e, 0x61, 0x63, 0x74, 0x69, 0x76, 0x65, 0x20, 0x65, + 0x70, 0x20, 0x25, 0x64, 0x20, 0x25, 0x73, 0x00, 0x6f, 0x75, 0x74, 0x00, + 0x69, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x05, 0x00, 0x20, 0x49, 0x4e, 0x46, 0x00, + 0x69, 0x6e, 0x66, 0x00, 0x4e, 0x41, 0x4e, 0x00, 0x6e, 0x61, 0x6e, 0x00, + 0x30, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x00, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x00, + 0x65, 0x25, 0x6c, 0x64, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, + 0xce, 0xfb, 0xff, 0xff, 0xcb, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xce, 0xfb, 0xff, 0xff, + 0xcb, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xbc, 0x89, 0xd8, 0x97, 0xb2, 0xd2, 0x9c, 0x3c, 0x33, 0xa7, 0xa8, 0xd5, + 0x23, 0xf6, 0x49, 0x39, 0x3d, 0xa7, 0xf4, 0x44, 0xfd, 0x0f, 0xa5, 0x32, + 0x9d, 0x97, 0x8c, 0xcf, 0x08, 0xba, 0x5b, 0x25, 0x43, 0x6f, 0xac, 0x64, + 0x28, 0x06, 0x68, 0x11, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x28, 0x28, 0x28, 0x28, 0x28, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, + 0x20, 0x88, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x41, 0x41, + 0x41, 0x41, 0x41, 0x41, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x10, 0x10, 0x10, 0x10, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x6e, 0x66, + 0x69, 0x6e, 0x69, 0x74, 0x79, 0x00, 0x4e, 0x61, 0x4e, 0x00, 0x52, 0x45, + 0x45, 0x4e, 0x54, 0x20, 0x6d, 0x61, 0x6c, 0x6c, 0x6f, 0x63, 0x20, 0x73, + 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x00, 0x2f, 0x77, 0x6f, + 0x72, 0x6b, 0x64, 0x69, 0x72, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x2f, 0x6e, + 0x65, 0x77, 0x6c, 0x69, 0x62, 0x2f, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x62, + 0x2f, 0x6c, 0x69, 0x62, 0x63, 0x2f, 0x73, 0x74, 0x64, 0x6c, 0x69, 0x62, + 0x2f, 0x64, 0x74, 0x6f, 0x61, 0x2e, 0x63, 0x00, 0x42, 0x61, 0x6c, 0x6c, + 0x6f, 0x63, 0x20, 0x73, 0x75, 0x63, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, + 0x00, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x64, 0x69, 0x72, 0x2f, 0x72, 0x65, + 0x70, 0x6f, 0x2f, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x62, 0x2f, 0x6e, 0x65, + 0x77, 0x6c, 0x69, 0x62, 0x2f, 0x6c, 0x69, 0x62, 0x63, 0x2f, 0x73, 0x74, + 0x64, 0x6c, 0x69, 0x62, 0x2f, 0x67, 0x64, 0x74, 0x6f, 0x61, 0x2d, 0x67, + 0x65, 0x74, 0x68, 0x65, 0x78, 0x2e, 0x63, 0x00, 0x2e, 0x00, 0x00, 0x00, + 0xc4, 0x03, 0x01, 0x10, 0x11, 0xfd, 0x00, 0x10, 0xa0, 0x0a, 0x00, 0x20, + 0x50, 0x4f, 0x53, 0x49, 0x58, 0x00, 0x2f, 0x77, 0x6f, 0x72, 0x6b, 0x64, + 0x69, 0x72, 0x2f, 0x72, 0x65, 0x70, 0x6f, 0x2f, 0x6e, 0x65, 0x77, 0x6c, + 0x69, 0x62, 0x2f, 0x6e, 0x65, 0x77, 0x6c, 0x69, 0x62, 0x2f, 0x6c, 0x69, + 0x62, 0x63, 0x2f, 0x73, 0x74, 0x64, 0x6c, 0x69, 0x62, 0x2f, 0x6d, 0x70, + 0x72, 0x65, 0x63, 0x2e, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x7d, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xbc, 0x89, 0xd8, 0x97, 0xb2, 0xd2, 0x9c, 0x3c, + 0x33, 0xa7, 0xa8, 0xd5, 0x23, 0xf6, 0x49, 0x39, 0x3d, 0xa7, 0xf4, 0x44, + 0xfd, 0x0f, 0xa5, 0x32, 0x9d, 0x97, 0x8c, 0xcf, 0x08, 0xba, 0x5b, 0x25, + 0x43, 0x6f, 0xac, 0x64, 0x28, 0x06, 0xc8, 0x0a, 0x00, 0x80, 0xe0, 0x37, + 0x79, 0xc3, 0x41, 0x43, 0x17, 0x6e, 0x05, 0xb5, 0xb5, 0xb8, 0x93, 0x46, + 0xf5, 0xf9, 0x3f, 0xe9, 0x03, 0x4f, 0x38, 0x4d, 0x32, 0x1d, 0x30, 0xf9, + 0x48, 0x77, 0x82, 0x5a, 0x3c, 0xbf, 0x73, 0x7f, 0xdd, 0x4f, 0x15, 0x75, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x24, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x8f, 0x40, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x88, 0xc3, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0xf8, 0x40, + 0x00, 0x00, 0x00, 0x00, 0x80, 0x84, 0x2e, 0x41, 0x00, 0x00, 0x00, 0x00, + 0xd0, 0x12, 0x63, 0x41, 0x00, 0x00, 0x00, 0x00, 0x84, 0xd7, 0x97, 0x41, + 0x00, 0x00, 0x00, 0x00, 0x65, 0xcd, 0xcd, 0x41, 0x00, 0x00, 0x00, 0x20, + 0x5f, 0xa0, 0x02, 0x42, 0x00, 0x00, 0x00, 0xe8, 0x76, 0x48, 0x37, 0x42, + 0x00, 0x00, 0x00, 0xa2, 0x94, 0x1a, 0x6d, 0x42, 0x00, 0x00, 0x40, 0xe5, + 0x9c, 0x30, 0xa2, 0x42, 0x00, 0x00, 0x90, 0x1e, 0xc4, 0xbc, 0xd6, 0x42, + 0x00, 0x00, 0x34, 0x26, 0xf5, 0x6b, 0x0c, 0x43, 0x00, 0x80, 0xe0, 0x37, + 0x79, 0xc3, 0x41, 0x43, 0x00, 0xa0, 0xd8, 0x85, 0x57, 0x34, 0x76, 0x43, + 0x00, 0xc8, 0x4e, 0x67, 0x6d, 0xc1, 0xab, 0x43, 0x00, 0x3d, 0x91, 0x60, + 0xe4, 0x58, 0xe1, 0x43, 0x40, 0x8c, 0xb5, 0x78, 0x1d, 0xaf, 0x15, 0x44, + 0x50, 0xef, 0xe2, 0xd6, 0xe4, 0x1a, 0x4b, 0x44, 0x92, 0xd5, 0x4d, 0x06, + 0xcf, 0xf0, 0x80, 0x44, 0xf6, 0x4a, 0xe1, 0xc7, 0x02, 0x2d, 0xb5, 0x44, + 0xb4, 0x9d, 0xd9, 0x79, 0x43, 0x78, 0xea, 0x44, 0x23, 0x2d, 0x30, 0x2b, + 0x20, 0x00, 0x68, 0x6c, 0x4c, 0x00, 0x65, 0x66, 0x67, 0x45, 0x46, 0x47, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x4b, 0x70, 0xb5, 0x1b, 0x78, 0x00, 0x2b, + 0x15, 0xd1, 0xd0, 0x25, 0xff, 0x33, 0x2d, 0x06, 0x2b, 0x65, 0x00, 0xf0, + 0xe5, 0xf9, 0x01, 0x24, 0x2b, 0x6d, 0x23, 0x42, 0x09, 0xd0, 0x00, 0xf0, + 0xbf, 0xf9, 0x06, 0x4b, 0x98, 0x42, 0xf7, 0xd1, 0x05, 0x4b, 0x1c, 0x70, + 0x1a, 0x78, 0x00, 0x2a, 0xfc, 0xd1, 0x00, 0xf0, 0xdd, 0xf9, 0x70, 0xbd, + 0xce, 0x1a, 0x00, 0x20, 0x2e, 0xd0, 0xde, 0xc0, 0xcf, 0x1a, 0x00, 0x20, + 0xd0, 0x23, 0x30, 0xb5, 0x00, 0x24, 0x00, 0x21, 0x1b, 0x06, 0x1c, 0x57, + 0x05, 0x68, 0xef, 0xf3, 0x10, 0x83, 0x72, 0xb6, 0x2a, 0x68, 0x00, 0x2a, + 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x05, 0x79, 0x02, 0x68, 0x7f, 0x2d, + 0x06, 0xd9, 0x04, 0x71, 0xbf, 0xf3, 0x5f, 0x8f, 0x11, 0x60, 0x83, 0xf3, + 0x10, 0x88, 0x30, 0xbd, 0xbf, 0xf3, 0x5f, 0x8f, 0x11, 0x60, 0x83, 0xf3, + 0x10, 0x88, 0x20, 0xbf, 0xe4, 0xe7, 0xd0, 0x23, 0x30, 0xb5, 0x00, 0x25, + 0x1b, 0x06, 0x1b, 0x78, 0x5b, 0xb2, 0x04, 0x68, 0xef, 0xf3, 0x10, 0x82, + 0x72, 0xb6, 0x21, 0x68, 0x00, 0x29, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, + 0x04, 0x24, 0x04, 0x57, 0x01, 0x68, 0x9c, 0x42, 0x01, 0xd0, 0x00, 0x2c, + 0x0a, 0xda, 0x03, 0x71, 0x43, 0x79, 0x01, 0x33, 0x43, 0x71, 0xbf, 0xf3, + 0x5f, 0x8f, 0x00, 0x23, 0x0b, 0x60, 0x82, 0xf3, 0x10, 0x88, 0x30, 0xbd, + 0xbf, 0xf3, 0x5f, 0x8f, 0x0d, 0x60, 0x82, 0xf3, 0x10, 0x88, 0x20, 0xbf, + 0xdd, 0xe7, 0x03, 0x00, 0x10, 0xb5, 0x00, 0x68, 0xef, 0xf3, 0x10, 0x84, + 0x72, 0xb6, 0x02, 0x68, 0x00, 0x2a, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, + 0x04, 0x22, 0x9a, 0x56, 0x00, 0x2a, 0x0c, 0xda, 0xd0, 0x22, 0x01, 0x20, + 0x12, 0x06, 0x12, 0x68, 0x1a, 0x71, 0x1b, 0x68, 0xbf, 0xf3, 0x5f, 0x8f, + 0x00, 0x22, 0x1a, 0x60, 0x84, 0xf3, 0x10, 0x88, 0x10, 0xbd, 0x08, 0x1e, + 0xf5, 0xd0, 0x00, 0x20, 0x0a, 0x60, 0xf2, 0xe7, 0xf7, 0xb5, 0x1e, 0x00, + 0xd0, 0x23, 0x05, 0x00, 0x17, 0x00, 0x1b, 0x06, 0x1b, 0x68, 0x01, 0x93, + 0x29, 0x68, 0xef, 0xf3, 0x10, 0x83, 0x72, 0xb6, 0x0a, 0x68, 0x00, 0x2a, + 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0x29, 0x79, 0x00, 0x24, 0x2a, 0x68, + 0x7f, 0x29, 0x08, 0xd9, 0x01, 0x99, 0x29, 0x71, 0xbf, 0xf3, 0x5f, 0x8f, + 0x14, 0x60, 0x83, 0xf3, 0x10, 0x88, 0x01, 0x20, 0xfe, 0xbd, 0xbf, 0xf3, + 0x5f, 0x8f, 0x14, 0x60, 0x83, 0xf3, 0x10, 0x88, 0x38, 0x00, 0x31, 0x00, + 0x00, 0xf0, 0x34, 0xf9, 0x00, 0x28, 0xdd, 0xd0, 0x20, 0x00, 0xf1, 0xe7, + 0xf8, 0xb5, 0x0f, 0x00, 0x06, 0x00, 0x00, 0xf0, 0x23, 0xf9, 0xfa, 0x22, + 0x04, 0x00, 0x0d, 0x00, 0x00, 0x23, 0x92, 0x00, 0x38, 0x00, 0x00, 0x21, + 0x00, 0xf0, 0x12, 0xf9, 0x02, 0x00, 0x0b, 0x00, 0x12, 0x19, 0x6b, 0x41, + 0x9d, 0x42, 0x02, 0xd8, 0x04, 0xd1, 0x94, 0x42, 0x02, 0xd9, 0x01, 0x22, + 0x52, 0x42, 0xd3, 0x17, 0x30, 0x00, 0xff, 0xf7, 0xb7, 0xff, 0xf8, 0xbd, + 0x01, 0x68, 0xef, 0xf3, 0x10, 0x83, 0x72, 0xb6, 0x0a, 0x68, 0x00, 0x2a, + 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, 0xff, 0x22, 0x02, 0x71, 0x02, 0x68, + 0xbf, 0xf3, 0x5f, 0x8f, 0x00, 0x21, 0x11, 0x60, 0x83, 0xf3, 0x10, 0x88, + 0x40, 0xbf, 0x70, 0x47, 0x10, 0xb5, 0x01, 0x68, 0xef, 0xf3, 0x10, 0x82, + 0x72, 0xb6, 0x0b, 0x68, 0x00, 0x2b, 0xfc, 0xd0, 0xbf, 0xf3, 0x5f, 0x8f, + 0x43, 0x79, 0x01, 0x68, 0x01, 0x3b, 0xdb, 0xb2, 0x43, 0x71, 0x00, 0x2b, + 0x08, 0xd1, 0xff, 0x24, 0x04, 0x71, 0xbf, 0xf3, 0x5f, 0x8f, 0x0b, 0x60, + 0x82, 0xf3, 0x10, 0x88, 0x40, 0xbf, 0x10, 0xbd, 0xbf, 0xf3, 0x5f, 0x8f, + 0x00, 0x23, 0x0b, 0x60, 0x82, 0xf3, 0x10, 0x88, 0xf7, 0xe7, 0x00, 0x00, + 0x08, 0x4a, 0x10, 0xb5, 0x13, 0x78, 0x00, 0x2b, 0x0a, 0xd1, 0x80, 0x23, + 0x06, 0x48, 0x07, 0x49, 0x5b, 0x05, 0x1c, 0x68, 0xc4, 0x50, 0x04, 0x33, + 0x8b, 0x42, 0xfa, 0xd1, 0x01, 0x23, 0x13, 0x70, 0x10, 0xbd, 0xc0, 0x46, + 0xe5, 0x1b, 0x00, 0x20, 0x34, 0x13, 0x00, 0x10, 0x00, 0x01, 0x00, 0x10, + 0x10, 0xb5, 0x02, 0x4b, 0x01, 0x33, 0x98, 0x47, 0x10, 0xbd, 0xc0, 0x46, + 0x34, 0x13, 0x00, 0x20, 0x43, 0x1e, 0x98, 0x41, 0x05, 0x4b, 0x02, 0x30, + 0x1b, 0x68, 0x00, 0x02, 0x58, 0x40, 0xc0, 0x23, 0x9b, 0x00, 0x18, 0x40, + 0x02, 0x4b, 0x18, 0x60, 0x70, 0x47, 0xc0, 0x46, 0x0c, 0x80, 0x01, 0x40, + 0x0c, 0x90, 0x01, 0x40, 0xf0, 0xb5, 0x14, 0x27, 0x18, 0x26, 0x85, 0xb0, + 0x33, 0x88, 0x01, 0x90, 0x02, 0x91, 0x38, 0x88, 0x21, 0x49, 0x14, 0x00, + 0x98, 0x47, 0x33, 0x88, 0x05, 0x00, 0x20, 0x49, 0x38, 0x88, 0x98, 0x47, + 0x33, 0x88, 0x1f, 0x49, 0x03, 0x90, 0x38, 0x88, 0x98, 0x47, 0x06, 0x00, + 0xff, 0xf7, 0xb6, 0xff, 0xa8, 0x47, 0x03, 0x9b, 0x98, 0x47, 0x00, 0x20, + 0xff, 0xf7, 0xd0, 0xff, 0xc0, 0x22, 0x23, 0x00, 0x08, 0x20, 0x52, 0x05, + 0x12, 0x3f, 0x21, 0x00, 0x19, 0x43, 0x07, 0xd1, 0x01, 0x20, 0xff, 0xf7, + 0xc5, 0xff, 0xb0, 0x47, 0xff, 0xf7, 0xba, 0xff, 0x05, 0xb0, 0xf0, 0xbd, + 0x91, 0x6a, 0x0d, 0x00, 0x05, 0x40, 0x39, 0x42, 0x0b, 0xd0, 0x00, 0x2c, + 0x09, 0xd0, 0x19, 0x1b, 0x0d, 0x29, 0x06, 0xd8, 0x01, 0x99, 0x01, 0x3c, + 0x09, 0x78, 0x11, 0x66, 0x01, 0x99, 0x01, 0x31, 0x01, 0x91, 0x00, 0x2d, + 0xe1, 0xd0, 0x00, 0x2b, 0xdf, 0xd0, 0x11, 0x6e, 0x02, 0x9d, 0x01, 0x3b, + 0x29, 0x70, 0x29, 0x00, 0x01, 0x31, 0x02, 0x91, 0xd7, 0xe7, 0xc0, 0x46, + 0x49, 0x46, 0x00, 0x00, 0x45, 0x58, 0x00, 0x00, 0x46, 0x43, 0x00, 0x00, + 0x10, 0xb5, 0x88, 0x42, 0x02, 0xd9, 0x8b, 0x18, 0x98, 0x42, 0x03, 0xd3, + 0x00, 0x23, 0x07, 0xe0, 0x8b, 0x5c, 0x83, 0x54, 0x01, 0x3a, 0xfb, 0xd2, + 0x10, 0xbd, 0xcc, 0x5c, 0xc4, 0x54, 0x01, 0x33, 0x9a, 0x42, 0xfa, 0xd1, + 0xf8, 0xe7, 0xc9, 0xb2, 0x82, 0x18, 0x90, 0x42, 0x01, 0xd1, 0x00, 0x20, + 0x70, 0x47, 0x03, 0x78, 0x8b, 0x42, 0xfb, 0xd0, 0x01, 0x30, 0xf6, 0xe7, + 0x02, 0xb4, 0x71, 0x46, 0x49, 0x08, 0x49, 0x00, 0x09, 0x5c, 0x49, 0x00, + 0x8e, 0x44, 0x02, 0xbc, 0x70, 0x47, 0xc0, 0x46, 0x03, 0xb4, 0x71, 0x46, + 0x49, 0x08, 0x40, 0x00, 0x49, 0x00, 0x09, 0x5e, 0x49, 0x00, 0x8e, 0x44, + 0x03, 0xbc, 0x70, 0x47, 0x03, 0xb4, 0x71, 0x46, 0x49, 0x08, 0x40, 0x00, + 0x49, 0x00, 0x09, 0x5a, 0x49, 0x00, 0x8e, 0x44, 0x03, 0xbc, 0x70, 0x47, + 0x70, 0x47, 0xc0, 0x46, 0x00, 0x00, 0x00, 0x00, 0x01, 0xb4, 0x02, 0x48, + 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, 0x5d, 0x75, 0x00, 0x10, + 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, + 0xad, 0x74, 0x00, 0x10, 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, + 0x60, 0x47, 0x00, 0xbf, 0x8d, 0x5d, 0x00, 0x10, 0x01, 0xb4, 0x02, 0x48, + 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, 0xa5, 0x5c, 0x00, 0x10, + 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, 0x60, 0x47, 0x00, 0xbf, + 0x49, 0x4a, 0x00, 0x10, 0x01, 0xb4, 0x02, 0x48, 0x84, 0x46, 0x01, 0xbc, + 0x60, 0x47, 0x00, 0xbf, 0xf1, 0x49, 0x00, 0x10, 0x00, 0xc2, 0x01, 0x00, + 0x12, 0x01, 0x00, 0x02, 0x02, 0x02, 0x01, 0x40, 0x8a, 0x2e, 0x0a, 0x00, + 0x00, 0x01, 0x01, 0x02, 0x03, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0x48, 0x68, + 0x01, 0x31, 0x8e, 0x46, 0x00, 0x47, 0x70, 0x46, 0x09, 0x38, 0x01, 0x49, + 0x88, 0x47, 0x00, 0xbd, 0x21, 0x56, 0x00, 0x10, 0x38, 0x05, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x90, 0x0c, 0x00, 0x20, 0xe8, 0x1b, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x1b, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x33, 0x00, 0x00, + 0x4c, 0x33, 0x00, 0x00, 0x54, 0x33, 0x00, 0x00, 0x52, 0x33, 0x00, 0x00, + 0x4d, 0x53, 0x00, 0x00, 0x4d, 0x43, 0x00, 0x00, 0x53, 0x34, 0x00, 0x00, + 0x43, 0x34, 0x00, 0x00, 0x25, 0x1b, 0x00, 0x20, 0x10, 0x00, 0x0c, 0x00, + 0x00, 0x00, 0xe0, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x30, 0x01, 0x01, 0x10, 0x34, 0x01, 0x01, 0x10, + 0xa0, 0x05, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x78, 0x01, 0x01, 0x10, + 0x58, 0x01, 0x01, 0x10, 0x38, 0x01, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x06, 0x00, 0x20, + 0x98, 0x06, 0x00, 0x20, 0xa0, 0x06, 0x00, 0x20, 0xa0, 0x06, 0x00, 0x20, + 0xa8, 0x06, 0x00, 0x20, 0xa8, 0x06, 0x00, 0x20, 0xb0, 0x06, 0x00, 0x20, + 0xb0, 0x06, 0x00, 0x20, 0xb8, 0x06, 0x00, 0x20, 0xb8, 0x06, 0x00, 0x20, + 0xc0, 0x06, 0x00, 0x20, 0xc0, 0x06, 0x00, 0x20, 0xc8, 0x06, 0x00, 0x20, + 0xc8, 0x06, 0x00, 0x20, 0xd0, 0x06, 0x00, 0x20, 0xd0, 0x06, 0x00, 0x20, + 0xd8, 0x06, 0x00, 0x20, 0xd8, 0x06, 0x00, 0x20, 0xe0, 0x06, 0x00, 0x20, + 0xe0, 0x06, 0x00, 0x20, 0xe8, 0x06, 0x00, 0x20, 0xe8, 0x06, 0x00, 0x20, + 0xf0, 0x06, 0x00, 0x20, 0xf0, 0x06, 0x00, 0x20, 0xf8, 0x06, 0x00, 0x20, + 0xf8, 0x06, 0x00, 0x20, 0x00, 0x07, 0x00, 0x20, 0x00, 0x07, 0x00, 0x20, + 0x08, 0x07, 0x00, 0x20, 0x08, 0x07, 0x00, 0x20, 0x10, 0x07, 0x00, 0x20, + 0x10, 0x07, 0x00, 0x20, 0x18, 0x07, 0x00, 0x20, 0x18, 0x07, 0x00, 0x20, + 0x20, 0x07, 0x00, 0x20, 0x20, 0x07, 0x00, 0x20, 0x28, 0x07, 0x00, 0x20, + 0x28, 0x07, 0x00, 0x20, 0x30, 0x07, 0x00, 0x20, 0x30, 0x07, 0x00, 0x20, + 0x38, 0x07, 0x00, 0x20, 0x38, 0x07, 0x00, 0x20, 0x40, 0x07, 0x00, 0x20, + 0x40, 0x07, 0x00, 0x20, 0x48, 0x07, 0x00, 0x20, 0x48, 0x07, 0x00, 0x20, + 0x50, 0x07, 0x00, 0x20, 0x50, 0x07, 0x00, 0x20, 0x58, 0x07, 0x00, 0x20, + 0x58, 0x07, 0x00, 0x20, 0x60, 0x07, 0x00, 0x20, 0x60, 0x07, 0x00, 0x20, + 0x68, 0x07, 0x00, 0x20, 0x68, 0x07, 0x00, 0x20, 0x70, 0x07, 0x00, 0x20, + 0x70, 0x07, 0x00, 0x20, 0x78, 0x07, 0x00, 0x20, 0x78, 0x07, 0x00, 0x20, + 0x80, 0x07, 0x00, 0x20, 0x80, 0x07, 0x00, 0x20, 0x88, 0x07, 0x00, 0x20, + 0x88, 0x07, 0x00, 0x20, 0x90, 0x07, 0x00, 0x20, 0x90, 0x07, 0x00, 0x20, + 0x98, 0x07, 0x00, 0x20, 0x98, 0x07, 0x00, 0x20, 0xa0, 0x07, 0x00, 0x20, + 0xa0, 0x07, 0x00, 0x20, 0xa8, 0x07, 0x00, 0x20, 0xa8, 0x07, 0x00, 0x20, + 0xb0, 0x07, 0x00, 0x20, 0xb0, 0x07, 0x00, 0x20, 0xb8, 0x07, 0x00, 0x20, + 0xb8, 0x07, 0x00, 0x20, 0xc0, 0x07, 0x00, 0x20, 0xc0, 0x07, 0x00, 0x20, + 0xc8, 0x07, 0x00, 0x20, 0xc8, 0x07, 0x00, 0x20, 0xd0, 0x07, 0x00, 0x20, + 0xd0, 0x07, 0x00, 0x20, 0xd8, 0x07, 0x00, 0x20, 0xd8, 0x07, 0x00, 0x20, + 0xe0, 0x07, 0x00, 0x20, 0xe0, 0x07, 0x00, 0x20, 0xe8, 0x07, 0x00, 0x20, + 0xe8, 0x07, 0x00, 0x20, 0xf0, 0x07, 0x00, 0x20, 0xf0, 0x07, 0x00, 0x20, + 0xf8, 0x07, 0x00, 0x20, 0xf8, 0x07, 0x00, 0x20, 0x00, 0x08, 0x00, 0x20, + 0x00, 0x08, 0x00, 0x20, 0x08, 0x08, 0x00, 0x20, 0x08, 0x08, 0x00, 0x20, + 0x10, 0x08, 0x00, 0x20, 0x10, 0x08, 0x00, 0x20, 0x18, 0x08, 0x00, 0x20, + 0x18, 0x08, 0x00, 0x20, 0x20, 0x08, 0x00, 0x20, 0x20, 0x08, 0x00, 0x20, + 0x28, 0x08, 0x00, 0x20, 0x28, 0x08, 0x00, 0x20, 0x30, 0x08, 0x00, 0x20, + 0x30, 0x08, 0x00, 0x20, 0x38, 0x08, 0x00, 0x20, 0x38, 0x08, 0x00, 0x20, + 0x40, 0x08, 0x00, 0x20, 0x40, 0x08, 0x00, 0x20, 0x48, 0x08, 0x00, 0x20, + 0x48, 0x08, 0x00, 0x20, 0x50, 0x08, 0x00, 0x20, 0x50, 0x08, 0x00, 0x20, + 0x58, 0x08, 0x00, 0x20, 0x58, 0x08, 0x00, 0x20, 0x60, 0x08, 0x00, 0x20, + 0x60, 0x08, 0x00, 0x20, 0x68, 0x08, 0x00, 0x20, 0x68, 0x08, 0x00, 0x20, + 0x70, 0x08, 0x00, 0x20, 0x70, 0x08, 0x00, 0x20, 0x78, 0x08, 0x00, 0x20, + 0x78, 0x08, 0x00, 0x20, 0x80, 0x08, 0x00, 0x20, 0x80, 0x08, 0x00, 0x20, + 0x88, 0x08, 0x00, 0x20, 0x88, 0x08, 0x00, 0x20, 0x90, 0x08, 0x00, 0x20, + 0x90, 0x08, 0x00, 0x20, 0x98, 0x08, 0x00, 0x20, 0x98, 0x08, 0x00, 0x20, + 0xa0, 0x08, 0x00, 0x20, 0xa0, 0x08, 0x00, 0x20, 0xa8, 0x08, 0x00, 0x20, + 0xa8, 0x08, 0x00, 0x20, 0xb0, 0x08, 0x00, 0x20, 0xb0, 0x08, 0x00, 0x20, + 0xb8, 0x08, 0x00, 0x20, 0xb8, 0x08, 0x00, 0x20, 0xc0, 0x08, 0x00, 0x20, + 0xc0, 0x08, 0x00, 0x20, 0xc8, 0x08, 0x00, 0x20, 0xc8, 0x08, 0x00, 0x20, + 0xd0, 0x08, 0x00, 0x20, 0xd0, 0x08, 0x00, 0x20, 0xd8, 0x08, 0x00, 0x20, + 0xd8, 0x08, 0x00, 0x20, 0xe0, 0x08, 0x00, 0x20, 0xe0, 0x08, 0x00, 0x20, + 0xe8, 0x08, 0x00, 0x20, 0xe8, 0x08, 0x00, 0x20, 0xf0, 0x08, 0x00, 0x20, + 0xf0, 0x08, 0x00, 0x20, 0xf8, 0x08, 0x00, 0x20, 0xf8, 0x08, 0x00, 0x20, + 0x00, 0x09, 0x00, 0x20, 0x00, 0x09, 0x00, 0x20, 0x08, 0x09, 0x00, 0x20, + 0x08, 0x09, 0x00, 0x20, 0x10, 0x09, 0x00, 0x20, 0x10, 0x09, 0x00, 0x20, + 0x18, 0x09, 0x00, 0x20, 0x18, 0x09, 0x00, 0x20, 0x20, 0x09, 0x00, 0x20, + 0x20, 0x09, 0x00, 0x20, 0x28, 0x09, 0x00, 0x20, 0x28, 0x09, 0x00, 0x20, + 0x30, 0x09, 0x00, 0x20, 0x30, 0x09, 0x00, 0x20, 0x38, 0x09, 0x00, 0x20, + 0x38, 0x09, 0x00, 0x20, 0x40, 0x09, 0x00, 0x20, 0x40, 0x09, 0x00, 0x20, + 0x48, 0x09, 0x00, 0x20, 0x48, 0x09, 0x00, 0x20, 0x50, 0x09, 0x00, 0x20, + 0x50, 0x09, 0x00, 0x20, 0x58, 0x09, 0x00, 0x20, 0x58, 0x09, 0x00, 0x20, + 0x60, 0x09, 0x00, 0x20, 0x60, 0x09, 0x00, 0x20, 0x68, 0x09, 0x00, 0x20, + 0x68, 0x09, 0x00, 0x20, 0x70, 0x09, 0x00, 0x20, 0x70, 0x09, 0x00, 0x20, + 0x78, 0x09, 0x00, 0x20, 0x78, 0x09, 0x00, 0x20, 0x80, 0x09, 0x00, 0x20, + 0x80, 0x09, 0x00, 0x20, 0x88, 0x09, 0x00, 0x20, 0x88, 0x09, 0x00, 0x20, + 0x90, 0x09, 0x00, 0x20, 0x90, 0x09, 0x00, 0x20, 0x98, 0x09, 0x00, 0x20, + 0x98, 0x09, 0x00, 0x20, 0xa0, 0x09, 0x00, 0x20, 0xa0, 0x09, 0x00, 0x20, + 0xa8, 0x09, 0x00, 0x20, 0xa8, 0x09, 0x00, 0x20, 0xb0, 0x09, 0x00, 0x20, + 0xb0, 0x09, 0x00, 0x20, 0xb8, 0x09, 0x00, 0x20, 0xb8, 0x09, 0x00, 0x20, + 0xc0, 0x09, 0x00, 0x20, 0xc0, 0x09, 0x00, 0x20, 0xc8, 0x09, 0x00, 0x20, + 0xc8, 0x09, 0x00, 0x20, 0xd0, 0x09, 0x00, 0x20, 0xd0, 0x09, 0x00, 0x20, + 0xd8, 0x09, 0x00, 0x20, 0xd8, 0x09, 0x00, 0x20, 0xe0, 0x09, 0x00, 0x20, + 0xe0, 0x09, 0x00, 0x20, 0xe8, 0x09, 0x00, 0x20, 0xe8, 0x09, 0x00, 0x20, + 0xf0, 0x09, 0x00, 0x20, 0xf0, 0x09, 0x00, 0x20, 0xf8, 0x09, 0x00, 0x20, + 0xf8, 0x09, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x20, + 0x08, 0x0a, 0x00, 0x20, 0x08, 0x0a, 0x00, 0x20, 0x10, 0x0a, 0x00, 0x20, + 0x10, 0x0a, 0x00, 0x20, 0x18, 0x0a, 0x00, 0x20, 0x18, 0x0a, 0x00, 0x20, + 0x20, 0x0a, 0x00, 0x20, 0x20, 0x0a, 0x00, 0x20, 0x28, 0x0a, 0x00, 0x20, + 0x28, 0x0a, 0x00, 0x20, 0x30, 0x0a, 0x00, 0x20, 0x30, 0x0a, 0x00, 0x20, + 0x38, 0x0a, 0x00, 0x20, 0x38, 0x0a, 0x00, 0x20, 0x40, 0x0a, 0x00, 0x20, + 0x40, 0x0a, 0x00, 0x20, 0x48, 0x0a, 0x00, 0x20, 0x48, 0x0a, 0x00, 0x20, + 0x50, 0x0a, 0x00, 0x20, 0x50, 0x0a, 0x00, 0x20, 0x58, 0x0a, 0x00, 0x20, + 0x58, 0x0a, 0x00, 0x20, 0x60, 0x0a, 0x00, 0x20, 0x60, 0x0a, 0x00, 0x20, + 0x68, 0x0a, 0x00, 0x20, 0x68, 0x0a, 0x00, 0x20, 0x70, 0x0a, 0x00, 0x20, + 0x70, 0x0a, 0x00, 0x20, 0x78, 0x0a, 0x00, 0x20, 0x78, 0x0a, 0x00, 0x20, + 0x80, 0x0a, 0x00, 0x20, 0x80, 0x0a, 0x00, 0x20, 0x88, 0x0a, 0x00, 0x20, + 0x88, 0x0a, 0x00, 0x20, 0x90, 0x0a, 0x00, 0x20, 0x90, 0x0a, 0x00, 0x20, + 0xff, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe5, 0xf6, 0x00, 0x10, 0xb5, 0xe0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x02, 0x01, 0x10, 0xc4, 0x03, 0x01, 0x10, 0x11, 0xfd, 0x00, 0x10, + 0x11, 0xfd, 0x00, 0x10, 0x11, 0xfd, 0x00, 0x10, 0x11, 0xfd, 0x00, 0x10, + 0x11, 0xfd, 0x00, 0x10, 0x11, 0xfd, 0x00, 0x10, 0x11, 0xfd, 0x00, 0x10, + 0x11, 0xfd, 0x00, 0x10, 0x11, 0xfd, 0x00, 0x10, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, + 0x01, 0x00, 0x41, 0x53, 0x43, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x53, + 0x43, 0x49, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xe1, 0x74, 0x00, 0x10, 0xdd, 0x63, 0x00, 0x10, + 0xf1, 0x6d, 0x00, 0x10, 0x8d, 0xfb, 0x00, 0x10, 0x09, 0x42, 0x00, 0x10, + 0xc1, 0x45, 0x00, 0x10, 0x9d, 0x48, 0x00, 0x10, 0xad, 0x4b, 0x00, 0x10, + 0xed, 0x63, 0x00, 0x10 +}; diff --git a/libraries/PicoOTA/keywords.txt b/libraries/PicoOTA/keywords.txt new file mode 100644 index 00000000..3cfd9aac --- /dev/null +++ b/libraries/PicoOTA/keywords.txt @@ -0,0 +1,21 @@ +####################################### +# Syntax Coloring Map For Ultrasound +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +picoOTA KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +addFile KEYWORD1 +commit KEYWORD1 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/PicoOTA/library.properties b/libraries/PicoOTA/library.properties new file mode 100644 index 00000000..7140b17e --- /dev/null +++ b/libraries/PicoOTA/library.properties @@ -0,0 +1,10 @@ +name=PicoOTA +version=1.0.0 +author=Earle F. Philhower, III +maintainer=Earle F. Philhower, III +sentence=Configures requests for OTA bootloader +paragraph=Example repository for Ethernet drivers +category=Device Control +url=https://github.com/earlephilhower.arduino-pico +architectures=rp2040 +dot_a_linkage=true diff --git a/libraries/PicoOTA/src/PicoOTA.cpp b/libraries/PicoOTA/src/PicoOTA.cpp new file mode 100644 index 00000000..9aae0190 --- /dev/null +++ b/libraries/PicoOTA/src/PicoOTA.cpp @@ -0,0 +1,22 @@ +/* + Pico_OTA.cpp - Programs OTA requests for RP2040 OTA + Copyright (c) 2022 Earle F. Philhower, III. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include + +PicoOTA picoOTA; diff --git a/libraries/PicoOTA/src/PicoOTA.h b/libraries/PicoOTA/src/PicoOTA.h new file mode 100644 index 00000000..fcfac482 --- /dev/null +++ b/libraries/PicoOTA/src/PicoOTA.h @@ -0,0 +1,144 @@ +/* + Pico_OTA.cpp - Programs OTA requests for RP2040 OTA + Copyright (c) 2022 Earle F. Philhower, III. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include +#include + +extern uint8_t _FS_start; +extern uint8_t _FS_end; + +// Simple and low code CRC calculation for the OTA page +class OTACRC32 { +public: + OTACRC32() { + crc = 0xffffffff; + } + + ~OTACRC32() { + } + + void add(const void *d, uint32_t len) { + const uint8_t *data = (const uint8_t *)d; + for (uint32_t i = 0; i < len; i++) { + crc ^= data[i]; + for (int j = 0; j < 8; j++) { + if (crc & 1) { + crc = (crc >> 1) ^ 0xedb88320; + } else { + crc >>= 1; + } + } + } + } + + uint32_t get() { + return ~crc; + } + +private: + uint32_t crc; +}; + + +// Handles generating valid OTA blocks +class PicoOTA { +public: + PicoOTA() { } + ~PicoOTA() { } + + void begin() { + if (_page) { + delete _page; + } + _page = new OTACmdPage; + memset(_page, 0, sizeof(*_page)); + memcpy(_page->sign, "Pico OTA Format\0", sizeof(_page->sign)); + _page->count = 0; + } + + bool addFile(const char *filename, uint32_t offset = 0, uint32_t flashaddr = XIP_BASE, uint32_t len = 0) { + if (!_page || _page->count == 8) { + return false; + } + File f = LittleFS.open(filename, "r"); + if (!f) { + return false; + } + if (!len) { + // Check for GZIP header, and if so read real length from file + uint8_t hdr[4]; + if (2 != f.read(hdr, 2)) { + // Error, this can't be valid + f.close(); + return false; + } + if ((hdr[0] == 0x1f) && (hdr[1] == 0x8b)) { + // GZIP signature matched. Find real size as encoded at the end + f.seek(f.size() - 4); + if (4 != f.read(hdr, 4)) { + f.close(); + return false; + } + len = hdr[0]; + len += hdr[1] << 8; + len += hdr[2] << 16; + len += hdr[3] << 24; + } else { + len = f.size(); + } + len -= offset; + } + f.close(); + _page->cmd[_page->count].command = _OTA_WRITE; + strncpy(_page->cmd[_page->count].write.filename, filename, sizeof(_page->cmd[_page->count].write.filename)); + _page->cmd[_page->count].write.fileOffset = offset; + _page->cmd[_page->count].write.fileLength = len; + _page->cmd[_page->count].write.flashAddress = flashaddr; + _page->count++; + return true; + } + + bool commit() { + if (!_page) { + return false; + } + + OTACRC32 crc; + crc.add(_page, offsetof(OTACmdPage, crc32)); + _page->crc32 = crc.get(); + + File f = LittleFS.open(_OTA_COMMAND_FILE, "w"); + if (!f) { + return false; + } + auto len = f.write((uint8_t *)_page, sizeof(*_page)); + f.close(); + + return len == sizeof(*_page); + } + +private: + OTACmdPage *_page = nullptr; +}; + +extern PicoOTA picoOTA; + diff --git a/libraries/SDFS/src/SDFS.cpp b/libraries/SDFS/src/SDFS.cpp index 5725a6ae..f40653ff 100644 --- a/libraries/SDFS/src/SDFS.cpp +++ b/libraries/SDFS/src/SDFS.cpp @@ -1,29 +1,29 @@ /* - SDFS.cpp - file system wrapper for SdFat - Copyright (c) 2019 Earle F. Philhower, III. All rights reserved. + SDFS.cpp - file system wrapper for SdFat + Copyright (c) 2019 Earle F. Philhower, III. All rights reserved. - Based on spiffs_api.cpp which is: - | Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + Based on spiffs_api.cpp which is: + | Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. - This code was influenced by NodeMCU and Sming libraries, and first version of - Arduino wrapper written by Hristo Gochkov. + This code was influenced by NodeMCU and Sming libraries, and first version of + Arduino wrapper written by Hristo Gochkov. - This file is part of the esp8266 core for Arduino environment. + This file is part of the esp8266 core for Arduino environment. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ #include "SDFS.h" #include @@ -39,8 +39,7 @@ namespace sdfs { // Required to be global because SDFAT doesn't allow a this pointer in it's own time call time_t (*__sdfs_timeCallback)(void) = nullptr; -FileImplPtr SDFSImpl::open(const char* path, OpenMode openMode, AccessMode accessMode) -{ +FileImplPtr SDFSImpl::open(const char* path, OpenMode openMode, AccessMode accessMode) { if (!_mounted) { DEBUGV("SDFSImpl::open() called on unmounted FS\n"); return FileImplPtr(); @@ -74,8 +73,7 @@ FileImplPtr SDFSImpl::open(const char* path, OpenMode openMode, AccessMode acces return std::make_shared(this, sharedFd, path); } -DirImplPtr SDFSImpl::openDir(const char* path) -{ +DirImplPtr SDFSImpl::openDir(const char* path) { if (!_mounted) { return DirImplPtr(); } @@ -85,8 +83,8 @@ DirImplPtr SDFSImpl::openDir(const char* path) return DirImplPtr(); } // Get rid of any trailing slashes - while (strlen(pathStr) && (pathStr[strlen(pathStr)-1]=='/')) { - pathStr[strlen(pathStr)-1] = 0; + while (strlen(pathStr) && (pathStr[strlen(pathStr) - 1] == '/')) { + pathStr[strlen(pathStr) - 1] = 0; } // At this point we have a name of "/blah/blah/blah" or "blah" or "" // If that references a directory, just open it and we're done. diff --git a/libraries/SDFS/src/SDFS.h b/libraries/SDFS/src/SDFS.h index 849c949f..aa05b287 100644 --- a/libraries/SDFS/src/SDFS.h +++ b/libraries/SDFS/src/SDFS.h @@ -2,31 +2,31 @@ #define SDFS_H /* - SDFS.h - file system wrapper for SdLib - Copyright (c) 2019 Earle F. Philhower, III. All rights reserved. + SDFS.h - file system wrapper for SdLib + Copyright (c) 2019 Earle F. Philhower, III. All rights reserved. - Based on spiffs_api.h, which is: - | Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. + Based on spiffs_api.h, which is: + | Copyright (c) 2015 Ivan Grokhotkov. All rights reserved. - This code was influenced by NodeMCU and Sming libraries, and first version of - Arduino wrapper written by Hristo Gochkov. + This code was influenced by NodeMCU and Sming libraries, and first version of + Arduino wrapper written by Hristo Gochkov. - This file is part of the esp8266 core for Arduino environment. + This file is part of the esp8266 core for Arduino environment. - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ #include #include #include "FS.h" @@ -41,8 +41,7 @@ namespace sdfs { class SDFSFileImpl; class SDFSDirImpl; -class SDFSConfig : public FSConfig -{ +class SDFSConfig : public FSConfig { public: static constexpr uint32_t FSId = 0x53444653; @@ -71,11 +70,9 @@ public: uint32_t _spiSettings; }; -class SDFSImpl : public FSImpl -{ +class SDFSImpl : public FSImpl { public: - SDFSImpl() : _mounted(false) - { + SDFSImpl() : _mounted(false) { } FileImplPtr open(const char* path, OpenMode openMode, AccessMode accessMode) override; @@ -99,7 +96,7 @@ public: info.blockSize = _fs.vol()->bytesPerCluster(); info.pageSize = 0; // TODO ? info.maxPathLength = 255; // TODO ? - info.totalBytes =_fs.vol()->clusterCount() * info.blockSize; + info.totalBytes = _fs.vol()->clusterCount() * info.blockSize; info.usedBytes = info.totalBytes - (_fs.vol()->freeClusterCount() * _fs.vol()->bytesPerCluster()); return true; } @@ -133,16 +130,15 @@ public: } bool rmdir(const char* path) override { - return _mounted ?_fs.rmdir(path) : false; + return _mounted ? _fs.rmdir(path) : false; } - bool setConfig(const FSConfig &cfg) override - { + bool setConfig(const FSConfig &cfg) override { if ((cfg._type != SDFSConfig::FSId) || _mounted) { DEBUGV("SDFS::setConfig: invalid config or already mounted\n"); return false; } - _cfg = *static_cast(&cfg); + _cfg = *static_cast(&cfg); return true; } @@ -155,7 +151,7 @@ public: format(); _mounted = _fs.begin(_cfg._csPin, _cfg._spiSettings); } - FsDateTime::setCallback(dateTimeCB); + FsDateTime::setCallback(dateTimeCB); return _mounted; } @@ -213,7 +209,7 @@ public: // static member of our class to return the time/date. static void dateTimeCB(uint16_t *dosYear, uint16_t *dosTime) { time_t now; - extern time_t (*__sdfs_timeCallback)(void); + extern time_t (*__sdfs_timeCallback)(void); if (__sdfs_timeCallback) { now = __sdfs_timeCallback(); } else { @@ -228,8 +224,7 @@ protected: friend class SDFileImpl; friend class SDFSDirImpl; - SdFat* getFs() - { + SdFat* getFs() { return &_fs; } @@ -261,76 +256,65 @@ protected: }; -class SDFSFileImpl : public FileImpl -{ +class SDFSFileImpl : public FileImpl { public: SDFSFileImpl(SDFSImpl *fs, std::shared_ptr fd, const char *name) - : _fs(fs), _fd(fd), _opened(true) - { + : _fs(fs), _fd(fd), _opened(true) { _name = std::shared_ptr(new char[strlen(name) + 1], std::default_delete()); strcpy(_name.get(), name); } - ~SDFSFileImpl() override - { + ~SDFSFileImpl() override { flush(); close(); } - int availableForWrite() override - { + int availableForWrite() override { return _opened ? _fd->availableSpaceForWrite() : 0; } - size_t write(const uint8_t *buf, size_t size) override - { + size_t write(const uint8_t *buf, size_t size) override { return _opened ? _fd->write(buf, size) : -1; } - int read(uint8_t* buf, size_t size) override - { + int read(uint8_t* buf, size_t size) override { return _opened ? _fd->read(buf, size) : -1; } - void flush() override - { + void flush() override { if (_opened) { _fd->sync(); } } - bool seek(uint32_t pos, SeekMode mode) override - { + bool seek(uint32_t pos, SeekMode mode) override { if (!_opened) { return false; } switch (mode) { - case SeekSet: - return _fd->seekSet(pos); - case SeekEnd: - return _fd->seekEnd(-pos); // TODO again, odd from POSIX - case SeekCur: - return _fd->seekCur(pos); - default: - // Should not be hit, we've got an invalid seek mode - DEBUGV("SDFSFileImpl::seek: invalid seek mode %d\n", mode); - assert((mode==SeekSet) || (mode==SeekEnd) || (mode==SeekCur)); // Will fail and give meaningful assert message - return false; + case SeekSet: + return _fd->seekSet(pos); + case SeekEnd: + return _fd->seekEnd(-pos); // TODO again, odd from POSIX + case SeekCur: + return _fd->seekCur(pos); + default: + // Should not be hit, we've got an invalid seek mode + DEBUGV("SDFSFileImpl::seek: invalid seek mode %d\n", mode); + assert((mode == SeekSet) || (mode == SeekEnd) || (mode == SeekCur)); // Will fail and give meaningful assert message + return false; } } - size_t position() const override - { + size_t position() const override { return _opened ? _fd->curPosition() : 0; } - size_t size() const override - { + size_t size() const override { return _opened ? _fd->fileSize() : 0; } - bool truncate(uint32_t size) override - { + bool truncate(uint32_t size) override { if (!_opened) { DEBUGV("SDFSFileImpl::truncate: file not opened\n"); return false; @@ -338,16 +322,14 @@ public: return _fd->truncate(size); } - void close() override - { + void close() override { if (_opened) { _fd->close(); _opened = false; } } - const char* name() const override - { + const char* name() const override { if (!_opened) { DEBUGV("SDFSFileImpl::name: file not opened\n"); return nullptr; @@ -362,18 +344,15 @@ public: } } - const char* fullName() const override - { + const char* fullName() const override { return _opened ? _name.get() : nullptr; } - bool isFile() const override - { + bool isFile() const override { return _opened ? _fd->isFile() : false;; } - bool isDirectory() const override - { + bool isDirectory() const override { return _opened ? _fd->isDir() : false; } @@ -406,36 +385,31 @@ protected: bool _opened; }; -class SDFSDirImpl : public DirImpl -{ +class SDFSDirImpl : public DirImpl { public: SDFSDirImpl(const String& pattern, SDFSImpl* fs, std::shared_ptr dir, const char *dirPath = nullptr) - : _pattern(pattern), _fs(fs), _dir(dir), _valid(false), _dirPath(nullptr) - { + : _pattern(pattern), _fs(fs), _dir(dir), _valid(false), _dirPath(nullptr) { if (dirPath) { _dirPath = std::shared_ptr(new char[strlen(dirPath) + 1], std::default_delete()); strcpy(_dirPath.get(), dirPath); } } - ~SDFSDirImpl() override - { + ~SDFSDirImpl() override { _dir->close(); } - FileImplPtr openFile(OpenMode openMode, AccessMode accessMode) override - { + FileImplPtr openFile(OpenMode openMode, AccessMode accessMode) override { if (!_valid) { return FileImplPtr(); } // MAX_PATH on FAT32 is potentially 260 bytes per most implementations char tmpName[260]; - snprintf(tmpName, sizeof(tmpName), "%s%s%s", _dirPath.get() ? _dirPath.get() : "", _dirPath.get()&&_dirPath.get()[0]?"/":"", _lfn); + snprintf(tmpName, sizeof(tmpName), "%s%s%s", _dirPath.get() ? _dirPath.get() : "", _dirPath.get() && _dirPath.get()[0] ? "/" : "", _lfn); return _fs->open((const char *)tmpName, openMode, accessMode); } - const char* fileName() override - { + const char* fileName() override { if (!_valid) { DEBUGV("SDFSDirImpl::fileName: directory not valid\n"); return nullptr; @@ -443,8 +417,7 @@ public: return (const char*) _lfn; //_dirent.name; } - size_t fileSize() override - { + size_t fileSize() override { if (!_valid) { return 0; } @@ -452,8 +425,7 @@ public: return _size; } - time_t fileTime() override - { + time_t fileTime() override { if (!_valid) { return 0; } @@ -461,8 +433,7 @@ public: return _time; } - time_t fileCreationTime() override - { + time_t fileCreationTime() override { if (!_valid) { return 0; } @@ -470,18 +441,15 @@ public: return _creation; } - bool isFile() const override - { + bool isFile() const override { return _valid ? _isFile : false; } - bool isDirectory() const override - { + bool isDirectory() const override { return _valid ? _isDirectory : false; } - bool next() override - { + bool next() override { const int n = _pattern.length(); do { File32 file; @@ -495,21 +463,20 @@ public: if (file.dirEntry(&tmp)) { _time = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.modifyDate, *(uint16_t*)tmp.modifyTime); _creation = SDFSImpl::FatToTimeT(*(uint16_t*)tmp.createDate, *(uint16_t*)tmp.createTime); - } else { + } else { _time = 0; _creation = 0; - } + } file.getName(_lfn, sizeof(_lfn)); file.close(); } else { _valid = 0; } - } while(_valid && strncmp((const char*) _lfn, _pattern.c_str(), n) != 0); + } while (_valid && strncmp((const char*) _lfn, _pattern.c_str(), n) != 0); return _valid; } - bool rewind() override - { + bool rewind() override { _valid = false; _dir->rewind(); return true; diff --git a/libraries/Updater/keywords.txt b/libraries/Updater/keywords.txt new file mode 100644 index 00000000..a3fe83dd --- /dev/null +++ b/libraries/Updater/keywords.txt @@ -0,0 +1,26 @@ +####################################### +# Syntax Coloring Map For Ultrasound +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +Updater KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +setup KEYWORD2 +handle KEYWORD2 +onStart KEYWORD2 +onEnd KEYWORD2 +onError KEYWORD2 +onProgress KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/Updater/library.properties b/libraries/Updater/library.properties new file mode 100644 index 00000000..5af011ed --- /dev/null +++ b/libraries/Updater/library.properties @@ -0,0 +1,10 @@ +name=Updater +version=1.0 +author=The ESP8266 Team +maintainer=Earle F. Philhower, III +sentence=Enables Over The Air upgrades, via wifi and espota.py UDP request/TCP download. +paragraph=With this library you can enable your sketch to be upgraded over network. Includes mdns announces to get discovered by the arduino IDE. +category=Communication +url=https://github.com/earlephilhower/arduino-pico +architectures=rp2040 +dot_a_linkage=true diff --git a/libraries/Updater/src/Updater.cpp b/libraries/Updater/src/Updater.cpp new file mode 100644 index 00000000..1d1e4362 --- /dev/null +++ b/libraries/Updater/src/Updater.cpp @@ -0,0 +1,443 @@ +/* + Updater - Handles FS or app updates using PicoOTA + Adapted from the ESP8266 Updater class + Copyright (c) 2022 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Updater.h" +#include +#include "StackThunk.h" +#include "LittleFS.h" +#include +#include + +#define DEBUG_UPDATER Serial + +#include +#ifndef ARDUINO_SIGNING +#define ARDUINO_SIGNING 0 +#endif + +extern uint8_t _FS_start; +extern uint8_t _FS_end; + + +#if ARDUINO_SIGNING +namespace esp8266 { +extern UpdaterHashClass& updaterSigningHash; +extern UpdaterVerifyClass& updaterSigningVerifier; +} +#endif + +UpdaterClass::UpdaterClass() { +#if ARDUINO_SIGNING + installSignature(&esp8266::updaterSigningHash, &esp8266::updaterSigningVerifier); + stack_thunk_add_ref(); +#endif +} + +UpdaterClass::~UpdaterClass() { +#if ARDUINO_SIGNING + stack_thunk_del_ref(); +#endif +} + +UpdaterClass& UpdaterClass::onProgress(THandlerFunction_Progress fn) { + _progress_callback = fn; + return *this; +} + +void UpdaterClass::_reset() { + if (_buffer) { + delete[] _buffer; + } + _buffer = 0; + _bufferLen = 0; + _startAddress = 0; + _currentAddress = 0; + _size = 0; + _command = U_FLASH; +} + +bool UpdaterClass::begin(size_t size, int command) { + uint32_t updateStartAddress; + if (_size > 0) { +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.println(F("[begin] already running")); +#endif + return false; + } + +#ifdef DEBUG_UPDATER + if (command == U_FS) { + DEBUG_UPDATER.println(F("[begin] Update Filesystem.")); + } +#endif + + if (size == 0) { + _setError(UPDATE_ERROR_SIZE); + return false; + } + + _reset(); + clearError(); // _error = 0 + _target_md5 = ""; + _md5 = MD5Builder(); + + if (command == U_FLASH) { + LittleFS.begin(); + _fp = LittleFS.open("firmware.bin", "w+"); + if (!_fp) { +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.println(F("[begin] unable to create file")); +#endif + return false; + } + updateStartAddress = 0; // Not used + } else if (command == U_FS) { + if (&_FS_start + size > &_FS_end) { + _setError(UPDATE_ERROR_SPACE); + return false; + } + + updateStartAddress = (uint32_t)&_FS_start; + } else { + // unknown command +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.println(F("[begin] Unknown update command.")); +#endif + return false; + } + + //initialize + _startAddress = updateStartAddress; + _size = size; + _bufferSize = 4096; + _buffer = new uint8_t[_bufferSize]; + _command = command; + +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.printf_P(PSTR("[begin] _startAddress: 0x%08X (%d)\n"), _startAddress, _startAddress); + DEBUG_UPDATER.printf_P(PSTR("[begin] _size: 0x%08zX (%zd)\n"), _size, _size); +#endif + + if (!_verify) { + _md5.begin(); + } + return true; +} + +bool UpdaterClass::setMD5(const char * expected_md5) { + if (strlen(expected_md5) != 32) { + return false; + } + _target_md5 = expected_md5; + return true; +} + +bool UpdaterClass::end(bool evenIfRemaining) { + if (_size == 0) { +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.println(F("no update")); +#endif + _reset(); + return false; + } + + // Updating w/o any data is an error we detect here + if (!progress()) { + _setError(UPDATE_ERROR_NO_DATA); + } + + if (hasError() || (!isFinished() && !evenIfRemaining)) { +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.printf_P(PSTR("premature end: res:%u, pos:%zu/%zu\n"), getError(), progress(), _size); +#endif + _reset(); + return false; + } + + if (evenIfRemaining) { + if (_bufferLen > 0) { + _writeBuffer(); + } + _size = progress(); + } + + if (_verify && (_command == U_FLASH)) { + const uint32_t expectedSigLen = _verify->length(); + // If expectedSigLen is non-zero, we expect the last four bytes of the buffer to + // contain a matching length field, preceded by the bytes of the signature itself. + // But if expectedSigLen is zero, we expect neither a signature nor a length field; + uint32_t sigLen = 0; + + if (expectedSigLen > 0) { + _fp.seek(_size - sizeof(uint32_t)); + _fp.read((uint8_t *)&sigLen, sizeof(uint32_t)); + } +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.printf_P(PSTR("[Updater] sigLen: %d\n"), sigLen); +#endif + if (sigLen != expectedSigLen) { + _setError(UPDATE_ERROR_SIGN); + _reset(); + return false; + } + + int binSize = _size; + if (expectedSigLen > 0) { + _size -= (sigLen + sizeof(uint32_t) /* The siglen word */); + } + _hash->begin(); +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.printf_P(PSTR("[Updater] Adjusted binsize: %d\n"), binSize); +#endif + // Calculate the MD5 and hash using proper size + uint8_t buff[128] __attribute__((aligned(4))); + _fp.seek(0); + for (int i = 0; i < binSize; i += sizeof(buff)) { + _fp.read(buff, sizeof(buff)); + size_t read = std::min((int)sizeof(buff), binSize - i); + _hash->add(buff, read); + } + _hash->end(); +#ifdef DEBUG_UPDATER + unsigned char *ret = (unsigned char *)_hash->hash(); + DEBUG_UPDATER.printf_P(PSTR("[Updater] Computed Hash:")); + for (int i = 0; i < _hash->len(); i++) { + DEBUG_UPDATER.printf(" %02x", ret[i]); + } + DEBUG_UPDATER.printf("\n"); +#endif + + uint8_t *sig = nullptr; // Safe to free if we don't actually malloc + if (expectedSigLen > 0) { + sig = (uint8_t*)malloc(sigLen); + if (!sig) { + _setError(UPDATE_ERROR_SIGN); + _reset(); + return false; + } + _fp.seek(_startAddress + binSize); + _fp.read((uint8_t *)sig, sigLen); +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.printf_P(PSTR("[Updater] Received Signature:")); + for (size_t i = 0; i < sigLen; i++) { + DEBUG_UPDATER.printf(" %02x", sig[i]); + } + DEBUG_UPDATER.printf("\n"); +#endif + } + if (!_verify->verify(_hash, (void *)sig, sigLen)) { + free(sig); + _setError(UPDATE_ERROR_SIGN); + _reset(); + return false; + } + free(sig); + _size = binSize; // Adjust size to remove signature, not part of bin payload + +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.printf_P(PSTR("[Updater] Signature matches\n")); +#endif + } else if (_target_md5.length()) { + _md5.calculate(); + if (strcasecmp(_target_md5.c_str(), _md5.toString().c_str())) { + _setError(UPDATE_ERROR_MD5); + return false; + } +#ifdef DEBUG_UPDATER + else { + DEBUG_UPDATER.printf_P(PSTR("MD5 Success: %s\n"), _target_md5.c_str()); + } +#endif + } + + if (!_verifyEnd()) { + _reset(); + return false; + } + + if (_command == U_FLASH) { + _fp.close(); + picoOTA.begin(); + picoOTA.addFile("firmware.bin"); + picoOTA.commit(); +#ifdef DEBUG_UPDATER + DEBUG_UPDATER.printf_P(PSTR("Staged: address:0x%08X, size:0x%08zX\n"), _startAddress, _size); +#endif + } + + _reset(); + return true; +} + +bool UpdaterClass::_writeBuffer() { + if (_command == U_FLASH) { + if (_bufferLen != _fp.write(_buffer, _bufferLen)) { + return false; + } + } else { + noInterrupts(); + rp2040.idleOtherCore(); + flash_range_erase((intptr_t)_currentAddress - (intptr_t)XIP_BASE, 4096); + flash_range_program((intptr_t)_currentAddress - (intptr_t)XIP_BASE, _buffer, 4096); + rp2040.resumeOtherCore(); + interrupts(); + } + if (!_verify) { + _md5.add(_buffer, _bufferLen); + } + _currentAddress += _bufferLen; + _bufferLen = 0; + return true; +} + +size_t UpdaterClass::write(uint8_t *data, size_t len) { + if (hasError() || !isRunning()) { + return 0; + } + + if (progress() + _bufferLen + len > _size) { + _setError(UPDATE_ERROR_SPACE); + return 0; + } + + size_t left = len; + + while ((_bufferLen + left) > _bufferSize) { + size_t toBuff = _bufferSize - _bufferLen; + memcpy(_buffer + _bufferLen, data + (len - left), toBuff); + _bufferLen += toBuff; + if (!_writeBuffer()) { + return len - left; + } + left -= toBuff; + if (!_async) { + yield(); + } + } + //lets see what's left + memcpy(_buffer + _bufferLen, data + (len - left), left); + _bufferLen += left; + if (_bufferLen == remaining()) { + //we are at the end of the update, so should write what's left to flash + if (!_writeBuffer()) { + return len - left; + } + } + return len; +} + +bool UpdaterClass::_verifyHeader(uint8_t data) { + (void) data; + // No special header on RP2040 + return true; +} + +bool UpdaterClass::_verifyEnd() { + return true; +} + +size_t UpdaterClass::writeStream(Stream &data, uint16_t streamTimeout) { + size_t written = 0; + size_t toRead = 0; + if (hasError() || !isRunning()) { + return 0; + } + + if (!_verifyHeader(data.peek())) { +#ifdef DEBUG_UPDATER + printError(DEBUG_UPDATER); +#endif + _reset(); + return 0; + } + esp8266::polledTimeout::oneShotMs timeOut(streamTimeout); + if (_progress_callback) { + _progress_callback(0, _size); + } + + while (remaining()) { + size_t bytesToRead = _bufferSize - _bufferLen; + if (bytesToRead > remaining()) { + bytesToRead = remaining(); + } + toRead = data.readBytes(_buffer + _bufferLen, bytesToRead); + if (toRead == 0) { //Timeout + if (timeOut) { + _currentAddress = (_startAddress + _size); + _setError(UPDATE_ERROR_STREAM); + _reset(); + return written; + } + delay(100); + } else { + timeOut.reset(); + } + _bufferLen += toRead; + if ((_bufferLen == remaining() || _bufferLen == _bufferSize) && !_writeBuffer()) { + return written; + } + written += toRead; + if (_progress_callback) { + _progress_callback(progress(), _size); + } + yield(); + } + if (_progress_callback) { + _progress_callback(progress(), _size); + } + return written; +} + +void UpdaterClass::_setError(int error) { + _error = error; +#ifdef DEBUG_UPDATER + printError(DEBUG_UPDATER); +#endif + _reset(); // Any error condition invalidates the entire update, so clear partial status +} + +void UpdaterClass::printError(Print &out) { + out.printf_P(PSTR("ERROR[%u]: "), _error); + if (_error == UPDATE_ERROR_OK) { + out.println(F("No Error")); + } else if (_error == UPDATE_ERROR_WRITE) { + out.println(F("Flash Write Failed")); + } else if (_error == UPDATE_ERROR_ERASE) { + out.println(F("Flash Erase Failed")); + } else if (_error == UPDATE_ERROR_READ) { + out.println(F("Flash Read Failed")); + } else if (_error == UPDATE_ERROR_SPACE) { + out.println(F("Not Enough Space")); + } else if (_error == UPDATE_ERROR_SIZE) { + out.println(F("Bad Size Given")); + } else if (_error == UPDATE_ERROR_STREAM) { + out.println(F("Stream Read Timeout")); + } else if (_error == UPDATE_ERROR_NO_DATA) { + out.println(F("No data supplied")); + } else if (_error == UPDATE_ERROR_MD5) { + out.printf_P(PSTR("MD5 Failed: expected:%s, calculated:%s\n"), _target_md5.c_str(), _md5.toString().c_str()); + } else if (_error == UPDATE_ERROR_SIGN) { + out.println(F("Signature verification failed")); + } else { + out.println(F("UNKNOWN")); + } +} + +UpdaterClass Update; diff --git a/libraries/Updater/src/Updater.h b/libraries/Updater/src/Updater.h new file mode 100644 index 00000000..3b329ef7 --- /dev/null +++ b/libraries/Updater/src/Updater.h @@ -0,0 +1,252 @@ +/* + Updater - Handles FS or app updates using PicoOTA + Adapted from the ESP8266 Updater class + Copyright (c) 2022 Earle F. Philhower, III + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include +#include +#include + +#define UPDATE_ERROR_OK (0) +#define UPDATE_ERROR_WRITE (1) +#define UPDATE_ERROR_ERASE (2) +#define UPDATE_ERROR_READ (3) +#define UPDATE_ERROR_SPACE (4) +#define UPDATE_ERROR_SIZE (5) +#define UPDATE_ERROR_STREAM (6) +#define UPDATE_ERROR_MD5 (7) +#define UPDATE_ERROR_FLASH_CONFIG (8) +#define UPDATE_ERROR_NEW_FLASH_CONFIG (9) +#define UPDATE_ERROR_MAGIC_BYTE (10) +#define UPDATE_ERROR_BOOTSTRAP (11) +#define UPDATE_ERROR_SIGN (12) +#define UPDATE_ERROR_NO_DATA (13) + +#define U_FLASH 0 +#define U_FS 100 +#define U_AUTH 200 + +#ifdef DEBUG_RP2040_PORT +#define DEBUG_UPDATER DEBUG_RP2040_PORT +#endif + +// Abstract class to implement whatever signing hash desired +class UpdaterHashClass { +public: + virtual void begin() = 0; + virtual void add(const void *data, uint32_t len) = 0; + virtual void end() = 0; + virtual int len() = 0; + virtual const void *hash() = 0; + virtual const unsigned char *oid() = 0; +}; + +// Abstract class to implement a signature verifier +class UpdaterVerifyClass { +public: + virtual uint32_t length() = 0; // How many bytes of signature are expected + virtual bool verify(UpdaterHashClass *hash, const void *signature, uint32_t signatureLen) = 0; // Verify, return "true" on success +}; + +class UpdaterClass { +public: + typedef std::function THandlerFunction_Progress; + + UpdaterClass(); + ~UpdaterClass(); + + /* Optionally add a cryptographic signature verification hash and method */ + void installSignature(UpdaterHashClass *hash, UpdaterVerifyClass *verify) { + _hash = hash; + _verify = verify; + } + + /* + Call this to check the space needed for the update + Will return false if there is not enough space + */ + bool begin(size_t size, int command = U_FLASH); + + /* + Run Updater from asynchronous callbacs + */ + void runAsync(bool async) { + _async = async; + } + + /* + Writes a buffer to the flash and increments the address + Returns the amount written + */ + size_t write(uint8_t *data, size_t len); + + /* + Writes the remaining bytes from the Stream to the flash + Uses readBytes() and sets UPDATE_ERROR_STREAM on timeout + Returns the bytes written + Should be equal to the remaining bytes when called + Usable for slow streams like Serial + */ + size_t writeStream(Stream &data, uint16_t streamTimeout = 60000); + + /* + If all bytes are written + this call will write the config to eboot + and return true + If there is already an update running but is not finished and !evenIfRemaining + or there is an error + this will clear everything and return false + the last error is available through getError() + evenIfRemaining is helpful when you update without knowing the final size first + */ + bool end(bool evenIfRemaining = false); + + /* + Prints the last error to an output stream + */ + void printError(Print &out); + + /* + sets the expected MD5 for the firmware (hexString) + */ + bool setMD5(const char * expected_md5); + + /* + returns the MD5 String of the successfully ended firmware + */ + String md5String(void) { + return _md5.toString(); + } + + /* + populated the result with the md5 bytes of the successfully ended firmware + */ + void md5(uint8_t * result) { + return _md5.getBytes(result); + } + + /* + This callback will be called when Updater is receiving data + */ + UpdaterClass& onProgress(THandlerFunction_Progress fn); + + //Helpers + uint8_t getError() { + return _error; + } + void clearError() { + _error = UPDATE_ERROR_OK; + } + bool hasError() { + return _error != UPDATE_ERROR_OK; + } + bool isRunning() { + return _size > 0; + } + bool isFinished() { + return _currentAddress == (_startAddress + _size); + } + size_t size() { + return _size; + } + size_t progress() { + return _currentAddress - _startAddress; + } + size_t remaining() { + return _size - (_currentAddress - _startAddress); + } + + /* + Template to write from objects that expose + available() and read(uint8_t*, size_t) methods + faster than the writeStream method + writes only what is available + */ + template + size_t write(T &data) { + size_t written = 0; + if (hasError() || !isRunning()) { + return 0; + } + + size_t available = data.available(); + while (available) { + if (_bufferLen + available > remaining()) { + available = remaining() - _bufferLen; + } + if (_bufferLen + available > _bufferSize) { + size_t toBuff = _bufferSize - _bufferLen; + data.read(_buffer + _bufferLen, toBuff); + _bufferLen += toBuff; + if (!_writeBuffer()) { + return written; + } + written += toBuff; + } else { + data.read(_buffer + _bufferLen, available); + _bufferLen += available; + written += available; + if (_bufferLen == remaining()) { + if (!_writeBuffer()) { + return written; + } + } + } + if (remaining() == 0) { + return written; + } + delay(1); + available = data.available(); + } + return written; + } + +private: + void _reset(); + bool _writeBuffer(); + + bool _verifyHeader(uint8_t data); + bool _verifyEnd(); + + void _setError(int error); + + bool _async = false; + uint8_t _error = 0; + uint8_t *_buffer = nullptr; + size_t _bufferLen = 0; // amount of data written into _buffer + size_t _bufferSize = 0; // total size of _buffer + size_t _size = 0; + uint32_t _startAddress = 0; + uint32_t _currentAddress = 0; + uint32_t _command = U_FLASH; + File _fp; + + String _target_md5; + MD5Builder _md5; + + // Optional signed binary verification + UpdaterHashClass *_hash = nullptr; + UpdaterVerifyClass *_verify = nullptr; + // Optional progress callback function + THandlerFunction_Progress _progress_callback = nullptr; +}; + +extern UpdaterClass Update; diff --git a/libraries/Updater/src/Updater_Signing.h b/libraries/Updater/src/Updater_Signing.h new file mode 100644 index 00000000..58f3089f --- /dev/null +++ b/libraries/Updater/src/Updater_Signing.h @@ -0,0 +1,3 @@ +// This file will be overridden when automatic signing is used. +// By default, no signing. +#define ARDUINO_SIGNING 0 diff --git a/libraries/WiFi/src/BearSSLHelpers.cpp b/libraries/WiFi/src/BearSSLHelpers.cpp index a7040c87..0def53b9 100644 --- a/libraries/WiFi/src/BearSSLHelpers.cpp +++ b/libraries/WiFi/src/BearSSLHelpers.cpp @@ -893,7 +893,7 @@ ServerSessions::ServerSessions(ServerSession *sessions, uint32_t size, bool isDy const br_ssl_session_cache_class **ServerSessions::getCache() { return _size > 0 ? &_cache.vtable : nullptr; } -#if 0 + // SHA256 hash for updater void HashSHA256::begin() { br_sha256_init(&_cc); @@ -954,7 +954,7 @@ extern "C" bool SigningVerifier_verify(PublicKey *_pubKey, UpdaterHashClass *has }; #if !CORE_MOCK -make_stack_thunk(SigningVerifier_verify); +make_stack_thunk_bool(SigningVerifier_verify, (PublicKey *_pubKey, UpdaterHashClass *hash, const void *signature, uint32_t signatureLen), (_pubKey, hash, signature, signatureLen)); extern "C" bool thunk_SigningVerifier_verify(PublicKey *_pubKey, UpdaterHashClass *hash, const void *signature, uint32_t signatureLen); #endif @@ -970,8 +970,6 @@ bool SigningVerifier::verify(UpdaterHashClass *hash, const void *signature, uint } -#endif - }; #if ARDUINO_SIGNING diff --git a/libraries/WiFi/src/BearSSLHelpers.h b/libraries/WiFi/src/BearSSLHelpers.h index 86fb89b3..ec619ea6 100644 --- a/libraries/WiFi/src/BearSSLHelpers.h +++ b/libraries/WiFi/src/BearSSLHelpers.h @@ -24,7 +24,8 @@ #include #include -//#include +#include +#include // Internal opaque structures, not needed by user applications namespace brssl { @@ -196,7 +197,6 @@ private: br_ssl_session_cache_lru _cache; }; -#if 0 // Updater SHA256 hash and signature verification class HashSHA256 : public UpdaterHashClass { @@ -230,7 +230,6 @@ private: PublicKey *_pubKey; }; -#endif }; diff --git a/libraries/WiFi/src/StackThunk.h b/libraries/WiFi/src/StackThunk.h index 1a320c6f..52862a94 100644 --- a/libraries/WiFi/src/StackThunk.h +++ b/libraries/WiFi/src/StackThunk.h @@ -43,6 +43,16 @@ extern "C" unsigned char * thunk_##fcnToThunk proto { \ return x; \ } +#define make_stack_thunk_bool(fcnToThunk, proto, params) \ +extern "C" bool thunk_##fcnToThunk proto { \ + register uint32_t* sp asm("sp"); \ + stack_thunk_save = sp; \ + sp = stack_thunk_top; \ + auto x = fcnToThunk params; \ + sp = stack_thunk_save; \ + return x; \ +} + #ifdef __cplusplus } #endif diff --git a/libraries/WiFi/src/WiFiClass.cpp b/libraries/WiFi/src/WiFiClass.cpp index 2f424c21..f92282a4 100644 --- a/libraries/WiFi/src/WiFiClass.cpp +++ b/libraries/WiFi/src/WiFiClass.cpp @@ -475,7 +475,7 @@ uint8_t WiFiClass::status() { } switch (cyw43_wifi_link_status(&cyw43_state, _apMode ? 1 : 0)) { case CYW43_LINK_DOWN: return WL_IDLE_STATUS; - case CYW43_LINK_JOIN: return localIP().isSet() ? WL_CONNECTED : WL_CONNECTING; + case CYW43_LINK_JOIN: return localIP().isSet() ? WL_CONNECTED : WL_DISCONNECTED; case CYW43_LINK_FAIL: return WL_CONNECT_FAILED; case CYW43_LINK_NONET: return WL_CONNECT_FAILED; case CYW43_LINK_BADAUTH: return WL_CONNECT_FAILED; diff --git a/libraries/WiFi/src/WiFiClass.h b/libraries/WiFi/src/WiFiClass.h index 426bae60..6e1e86cc 100644 --- a/libraries/WiFi/src/WiFiClass.h +++ b/libraries/WiFi/src/WiFiClass.h @@ -75,6 +75,16 @@ public: int begin(const char* ssid, const char *passphrase); bool connected(); + int8_t waitForConnectResult(unsigned long timeoutLength = 60000) { + uint32_t now = millis(); + while (millis() - now < timeoutLength) { + if (status() != WL_DISCONNECTED) { + return status(); + } + delay(10); + } + return -1; + } uint8_t beginAP(const char *ssid); uint8_t beginAP(const char *ssid, uint8_t channel); diff --git a/libraries/WiFi/src/include/UdpContext.h b/libraries/WiFi/src/include/UdpContext.h index 2d48ff80..bf4a6904 100644 --- a/libraries/WiFi/src/include/UdpContext.h +++ b/libraries/WiFi/src/include/UdpContext.h @@ -28,6 +28,7 @@ extern "C" { } #include +#include //#include #define PBUF_ALIGNER_ADJUST 4 diff --git a/libraries/WiFi/src/wl_definitions.h b/libraries/WiFi/src/wl_definitions.h index fdf240f9..dbeece0f 100644 --- a/libraries/WiFi/src/wl_definitions.h +++ b/libraries/WiFi/src/wl_definitions.h @@ -62,8 +62,7 @@ typedef enum { WL_DISCONNECTED, WL_AP_LISTENING, WL_AP_CONNECTED, - WL_AP_FAILED, - WL_CONNECTING + WL_AP_FAILED } wl_status_t; /* Encryption modes */ diff --git a/libraries/lwIP_Ethernet/src/AddrList.h b/libraries/lwIP_Ethernet/src/AddrList.h index 57710793..d7e5bc02 100644 --- a/libraries/lwIP_Ethernet/src/AddrList.h +++ b/libraries/lwIP_Ethernet/src/AddrList.h @@ -76,6 +76,9 @@ #define __ADDRLIST_H #include +#include +using IPAddress = arduino::IPAddress; +using String = arduino::String; #include #if LWIP_IPV6 diff --git a/ota/CMakeLists.txt b/ota/CMakeLists.txt new file mode 100644 index 00000000..9b225607 --- /dev/null +++ b/ota/CMakeLists.txt @@ -0,0 +1,85 @@ +cmake_minimum_required(VERSION 3.12) + +include(pico_sdk_import.cmake) + +project(pico_lib C CXX ASM) +set(CMAKE_C_STANDARD 11) +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_BUILD_TYPE RelWithDebInfo) + +set(PICO_BOARD pico) +set(PICO_COPY_TO_RAM 1) + +# Initialize the SDK +pico_sdk_init() + +add_executable(ota + ota.c + ota_lfs.c + ota_clocks.c + ../libraries/LittleFS/lib/littlefs/lfs.c + ../libraries/LittleFS/lib/littlefs/lfs_util.c + ./uzlib/src/tinflate.c + ./uzlib/src/tinfgzip.c +) +pico_add_extra_outputs(ota) +pico_enable_stdio_usb(ota 0) +pico_enable_stdio_uart(ota 0) + +# Use a longer XOSC startup time, to accommodate Adafruit and other boards that may need it. +target_compile_definitions(ota PUBLIC + PICO_FLASH_SIZE_BYTES=16777216 + PICO_XOSC_STARTUP_DELAY_MULTIPLIER=64 + PICO_RP2040_B0_SUPPORTED=1 + PICO_RP2040_B1_SUPPORTED=1 + PICO_RP2040_B2_SUPPORTED=1 + PICO_PRINTF_SUPPORT_FLOAT=0 + PICO_PRINTF_SUPPORT_LONG_LONG=0 + LIB_PICO_PRINTF_NONE=1 + LFS_READONLY=1 + LFS_NO_DEBUG=1 + LFS_NO_WARN=1 + LFS_NO_ERROR=1 + LFS_NO_ASSERT=1 + LFS_NO_MALLOC=1 + PICO_PANIC_FUNCTION= + PICO_TIME_DEFAULT_ALARM_POOL_DISABLED=1 +) + +target_compile_options(ota PUBLIC + -fno-exceptions + -Os + $<$:-fno-rtti> +) + +target_link_options(ota PUBLIC + -Wl,--wrap=clocks_init + -Wl,--wrap=exit + -Wl,--wrap=atexit + -Wl,--wrap=panic_unsupported + -Wl,--wrap=panic + -Wl,--wrap=hard_assertion_failure + -Wl,--cref +) + +set_target_properties(ota PROPERTIES PICO_TARGET_LINKER_SCRIPT + ${CMAKE_SOURCE_DIR}/memmap_ota.ld) + +target_link_libraries(ota + pico_platform + pico_standard_link + hardware_irq + hardware_flash + pico_time + hardware_gpio + hardware_uart + hardware_resets + hardware_clocks + pico_stdlib +) + +add_custom_command(TARGET ota POST_BUILD + COMMAND ../../system/arm-none-eabi/bin/arm-none-eabi-ld -r -A armv6-m -b binary -o ota.o ota.bin + COMMAND ../../system/arm-none-eabi/bin/arm-none-eabi-objcopy --rename-section .data=.OTA ota.o ../../lib/ota.o + COMMAND cp ../ota_command.h ../../include/pico_base/pico/. +) diff --git a/ota/README.md b/ota/README.md new file mode 100644 index 00000000..bffb4d83 --- /dev/null +++ b/ota/README.md @@ -0,0 +1,17 @@ +# Arduino-Pico OTA Bootloader + +This directory contains a small "stage 3" bootloader (after the boot ROM and the ``boot2.S`` flash configuration) which implements a power fail safe, generic OTA method. + +The bootloader is built here into an ``.ELF``, without ``boot2.S`` (which will come from the main app), configured to copy itself into RAM (so that it can update itself), and included in the main applications. Exactly ``12KB`` for all sketches is consumed by this OTA bootloader. + +It works by mounting the LittleFS file system (the parameters are stored by the main app at 0x3000-16), checking for a specially named command file. If that file exists, and its contents pass a checksum, the bootloader reads from the filesystem (optionally, automatically decompressing ``GZIP`` compressed files) and writes to application flash. + +Every block is checked to see if it identical to the block already in flash, and if so it is skipped. This allows silently skipping bootloader writes in many cases. + +Should a power failure happen, as long as it was not in the middle of writing a new OTA bootloader, it should simply begin copying the same program from scratch. + +When the copy is completed, the command file's contents are erased so that on a reboot it won't attempt to write the same firmware over and over. It then reboots the chip (and re-runs the potentially new bootloader). + +If there is no special file, or its contents don't have a proper checksum, the bootloaer simply adjusts the ARM internal vector pointers and jumps to the main application. + +The files in the LittleFS filesystem can come over ``WiFi``, over an ``Ethernet`` object, or even over a serial port. diff --git a/ota/make-ota.sh b/ota/make-ota.sh new file mode 100755 index 00000000..33491628 --- /dev/null +++ b/ota/make-ota.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -e # Exit on error + +export PICO_SDK_PATH="$(cd ../pico-sdk/; pwd)" +export PATH="$(cd ../../system/arm-none-eabi/bin; pwd):$PATH" + +rm -rf build +mkdir build +cd build +cmake .. +make -j # VERBOSE=1 diff --git a/ota/memmap_ota.ld b/ota/memmap_ota.ld new file mode 100644 index 00000000..a4f92d34 --- /dev/null +++ b/ota/memmap_ota.ld @@ -0,0 +1,253 @@ +/* Based on GCC ARM embedded samples. + Defines the following symbols for use by code: + __exidx_start + __exidx_end + __etext + __data_start__ + __preinit_array_start + __preinit_array_end + __init_array_start + __init_array_end + __fini_array_start + __fini_array_end + __data_end__ + __bss_start__ + __bss_end__ + __end__ + end + __HeapLimit + __StackLimit + __StackTop + __stack (== StackTop) +*/ + +MEMORY +{ + FLASH(rx) : ORIGIN = 0x10000100, LENGTH = 16384k + RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k + SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k + SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k +} + +ENTRY(_entry_point) + +SECTIONS +{ + /* Second stage bootloader is prepended to the image. It must be 256 bytes big + and checksummed. It is usually built by the boot_stage2 target + in the Raspberry Pi Pico SDK + */ + + .flash_begin : { + __flash_binary_start = .; + } > FLASH +/* + .boot2 : { + __boot2_start__ = .; + KEEP (*(.boot2)) + __boot2_end__ = .; + } > FLASH + + ASSERT(__boot2_end__ - __boot2_start__ == 256, + "ERROR: Pico second stage bootloader must be 256 bytes in size") +*/ + /* The second stage will always enter the image at the start of .text. + The debugger will use the ELF entry point, which is the _entry_point + symbol if present, otherwise defaults to start of .text. + This can be used to transfer control back to the bootrom on debugger + launches only, to perform proper flash setup. + */ + + .flashtext : { + __logical_binary_start = .; + KEEP (*(.vectors)) + KEEP (*(.binary_info_header)) + __binary_info_header_end = .; + KEEP (*(.reset)) + } + + .rodata : { + /* segments not marked as .flashdata are instead pulled into .data (in RAM) to avoid accidental flash accesses */ + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*))) + . = ALIGN(4); + } > FLASH + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + + /* Machine inspectable binary information */ + . = ALIGN(4); + __binary_info_start = .; + .binary_info : + { + KEEP(*(.binary_info.keep.*)) + *(.binary_info.*) + } > FLASH + __binary_info_end = .; + . = ALIGN(4); + + /* Vector table goes first in RAM, to avoid large alignment hole */ + .ram_vector_table (COPY): { + *(.ram_vector_table) + } > RAM + + .text : { + __ram_text_start__ = .; + *(.init) + *(.text*) + *(.fini) + /* Pull all c'tors into .text */ + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + /* Followed by destructors */ + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + + *(.eh_frame*) + . = ALIGN(4); + __ram_text_end__ = .; + } > RAM AT> FLASH + __ram_text_source__ = LOADADDR(.text); + + + .data : { + __data_start__ = .; + *(vtable) + + *(.time_critical*) + + . = ALIGN(4); + *(.rodata*) + . = ALIGN(4); + + *(.data*) + + . = ALIGN(4); + *(.after_data.*) + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__mutex_array_start = .); + KEEP(*(SORT(.mutex_array.*))) + KEEP(*(.mutex_array)) + PROVIDE_HIDDEN (__mutex_array_end = .); + + . = ALIGN(4); + /* preinit data */ + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(SORT(.preinit_array.*))) + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + /* init data */ + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + /* finit data */ + PROVIDE_HIDDEN (__fini_array_start = .); + *(SORT(.fini_array.*)) + *(.fini_array) + PROVIDE_HIDDEN (__fini_array_end = .); + + *(.jcr) + . = ALIGN(4); + /* All data end */ + __data_end__ = .; + } > RAM AT> FLASH + /* __etext is the name of the .data init source pointer (...) */ + __etext = LOADADDR(.data); + + .uninitialized_data (COPY): { + . = ALIGN(4); + *(.uninitialized_data*) + } > RAM + + /* Start and end symbols must be word-aligned */ + .scratch_x : { + __scratch_x_start__ = .; + *(.scratch_x.*) + . = ALIGN(4); + __scratch_x_end__ = .; + } > SCRATCH_X AT > FLASH + __scratch_x_source__ = LOADADDR(.scratch_x); + + .scratch_y : { + __scratch_y_start__ = .; + *(.scratch_y.*) + . = ALIGN(4); + __scratch_y_end__ = .; + } > SCRATCH_Y AT > FLASH + __scratch_y_source__ = LOADADDR(.scratch_y); + + .bss : { + . = ALIGN(4); + __bss_start__ = .; + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*))) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } > RAM + + .heap (COPY): + { + __end__ = .; + end = __end__; + *(.heap*) + __HeapLimit = .; + } > RAM + + /* .stack*_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later + * + * stack1 section may be empty/missing if platform_launch_core1 is not used */ + + /* by default we put core 0 stack at the end of scratch Y, so that if core 1 + * stack is not used then all of SCRATCH_X is free. + */ + .stack1_dummy (COPY): + { + *(.stack1*) + } > SCRATCH_X + .stack_dummy (COPY): + { + *(.stack*) + } > SCRATCH_Y + + .flash_end : { + __flash_binary_end = .; + } > FLASH + + /* stack limit is poorly named, but historically is maximum heap ptr */ + __StackLimit = ORIGIN(RAM) + LENGTH(RAM); + __StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X); + __StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y); + __StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy); + __StackBottom = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack = __StackTop); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed") + + ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary") + /* todo assert on extra code */ +} + diff --git a/ota/ota.c b/ota/ota.c new file mode 100644 index 00000000..22bd4f01 --- /dev/null +++ b/ota/ota.c @@ -0,0 +1,220 @@ +/* + ota.c - OTA stub that copies from LittleFS to flash + Copyright (c) 2022 Earle F. Philhower, III. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ota_lfs.h" +#include "ota_command.h" + +//#define DEBUG 1 + +#ifndef DEBUG +#define uart_putc(a, b) +#define uart_puts(a, b) +#endif + +uint8_t **__FS_START__ = (uint8_t **)(XIP_BASE + 0x3000 - 0x10 + 0x0); +uint8_t **__FS_END__ = (uint8_t **)(XIP_BASE + 0x3000 - 0x10 + 0x4); + +void dumphex(uint32_t x) { +#ifndef DEBUG + (void) x; +#else + uart_puts(uart0, "0x"); + for (int nibble = 7; nibble >= 0; nibble--) { + uint32_t n = 0x0f & (x >> (nibble * 4)); + char c = n < 10 ? '0' + n : 'A' + n - 10; + uart_putc(uart0, c); + } +#endif +} + +static OTACmdPage _ota_cmd; + +void do_ota() { + if (*__FS_START__ == *__FS_END__) { + return; + } + if (!lfsMount(*__FS_START__, 4096, *__FS_END__ - *__FS_START__)) { + uart_puts(uart0, "mount failed\n"); + return; + } + + // We are very naughty and record the last block read, since it should be the actual data block of the + // OTA structure. We'll erase it behind the scenes to avoid bringing in all of LittleFS write infra. + uint32_t blockToErase; + if (!lfsReadOTA(&_ota_cmd, &blockToErase)) { + return; + } + + if (memcmp(_ota_cmd.sign, "Pico OTA", 8)) { + return; // No signature + } + + uint32_t crc = 0xffffffff; + const uint8_t *data = (const uint8_t *)&_ota_cmd; + for (uint32_t i = 0; i < offsetof(OTACmdPage, crc32); i++) { + crc ^= data[i]; + for (int j = 0; j < 8; j++) { + if (crc & 1) { + crc = (crc >> 1) ^ 0xedb88320; + } else { + crc >>= 1; + } + } + } + crc = ~crc; + if (crc != _ota_cmd.crc32) { + uart_puts(uart0, "\ncrc32 mismatch\n"); + return; + } + + if (!_ota_cmd.count) { + uart_puts(uart0, "\nno ota count\n"); + return; + } + + for (uint32_t i = 0; i < _ota_cmd.count; i++) { + switch (_ota_cmd.cmd[i].command) { + case _OTA_WRITE: + uart_puts(uart0, "write: open "); + uart_puts(uart0, _ota_cmd.cmd[i].write.filename); + uart_puts(uart0, " = "); + if (!lfsOpen(_ota_cmd.cmd[i].write.filename)) { + uart_puts(uart0, "failed\n"); + return; + } + uart_puts(uart0, "success\n"); + uart_puts(uart0, "seek "); + dumphex(_ota_cmd.cmd[i].write.fileOffset); + uart_puts(uart0, " = "); + if (!lfsSeek(_ota_cmd.cmd[i].write.fileOffset)) { + uart_puts(uart0, "failed\n"); + return; + } + uart_puts(uart0, "success\n"); + uint32_t toRead = _ota_cmd.cmd[i].write.fileLength; + uint32_t toWrite = _ota_cmd.cmd[i].write.flashAddress; + + while (toRead) { + uint32_t len = (toRead < 4096) ? toRead : 4096; + uint8_t *p = lfsRead(len); + if (!p) { + uart_puts(uart0, "read failed\n"); + return; + } + uart_puts(uart0, "toread = "); + dumphex(toRead); + uart_puts(uart0, "\ntowrite = "); + dumphex(toWrite); + uart_puts(uart0, "\n"); + // Only write pages which differ (i.e. preserve OTA pages unless the OTA shim changes) + if (memcmp(p, (void*)toWrite, 4096)) { + uart_puts(uart0, "writing\n"); + int save = save_and_disable_interrupts(); + flash_range_erase((intptr_t)toWrite - XIP_BASE, 4096); + flash_range_program((intptr_t)toWrite - XIP_BASE, (const uint8_t *)p, 4096); + restore_interrupts(save); + } else { + uart_puts(uart0, "identical to flash, skipping\n"); + } + toRead -= len; + toWrite += 4096; + } + lfsClose(); + break; + default: + // TODO - verify + break; + } + } + + uart_puts(uart0, "\nota completed\n"); + + // Work completed, erase record. + lfsEraseBlock(blockToErase); + + // Do a hard reset just in case the start up sequence is not the same + watchdog_reboot(0, 0, 100); +} + + +#pragma GCC push_options +#pragma GCC optimize("O0") +int main(int a, unsigned char **b) { + (void) a; + (void) b; + +#ifdef DEBUG + uart_init(uart0, 115200); + gpio_set_function(0, GPIO_FUNC_UART); + gpio_set_function(1, GPIO_FUNC_UART); + uart_set_hw_flow(uart0, false, false); + uart_set_format(uart0, 8, 1, UART_PARITY_NONE); +#endif + + do_ota(); + + // Reset the interrupt/etc. vectors to the real app. Will be copied to RAM in app's runtime_init + scb_hw->vtor = (uint32_t)0x10003000; + + // Jump to it + register uint32_t* sp asm("sp"); + register uint32_t _sp = *(uint32_t *)0x10003000; + register void (*fcn)(void) = (void (*)(void)) *(uint32_t *)0x10003004; + sp = (uint32_t *)_sp; + fcn(); + + // Should never get here! + return 0; +} +#pragma GCC pop_options + +// Clear out some unwanted extra code +int __wrap_atexit(void (*function)(void)) { + (void) function; + return 0; +} + +// Clear out some unwanted extra code +void __wrap_exit(int status) { + (void) status; + while (1) continue; +} + +void __wrap_panic(const char *x) { + (void) x; + while (1) continue; +} + +void __wrap_panic_unsupported() { + while (1) continue; +} + +void __wrap_hard_assertion_failure() { + while (1) continue; +} diff --git a/ota/ota_clocks.c b/ota/ota_clocks.c new file mode 100644 index 00000000..71beb139 --- /dev/null +++ b/ota/ota_clocks.c @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* This file taken from the Pico SDK. clocks_init will now not require 64-bit division code */ + + +#include "pico.h" +#include "hardware/regs/clocks.h" +#include "hardware/platform_defs.h" +#include "hardware/clocks.h" +#include "hardware/watchdog.h" +#include "hardware/pll.h" +#include "hardware/xosc.h" +#include "hardware/irq.h" +#include "hardware/gpio.h" + +// Clock muxing consists of two components: +// - A glitchless mux, which can be switched freely, but whose inputs must be +// free-running +// - An auxiliary (glitchy) mux, whose output glitches when switched, but has +// no constraints on its inputs +// Not all clocks have both types of mux. +static inline bool has_glitchless_mux(enum clock_index clk_index) { + return clk_index == clk_sys || clk_index == clk_ref; +} + +/// \tag::clock_configure[] +bool _clock_configure(enum clock_index clk_index, uint32_t src, uint32_t auxsrc, uint32_t src_freq, uint32_t freq, uint32_t div) { + //uint32_t div; + + assert(src_freq >= freq); + + if (freq > src_freq) + return false; + + // Div register is 24.8 int.frac divider so multiply by 2^8 (left shift by 8) + //div = freq; //(uint32_t) (((uint64_t) src_freq << 8) / freq); + + clock_hw_t *clock = &clocks_hw->clk[clk_index]; + + // If increasing divisor, set divisor before source. Otherwise set source + // before divisor. This avoids a momentary overspeed when e.g. switching + // to a faster source and increasing divisor to compensate. + if (div > clock->div) + clock->div = div; + + // If switching a glitchless slice (ref or sys) to an aux source, switch + // away from aux *first* to avoid passing glitches when changing aux mux. + // Assume (!!!) glitchless source 0 is no faster than the aux source. + if (has_glitchless_mux(clk_index) && src == CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX) { + hw_clear_bits(&clock->ctrl, CLOCKS_CLK_REF_CTRL_SRC_BITS); + while (!(clock->selected & 1u)) + tight_loop_contents(); + } + // If no glitchless mux, cleanly stop the clock to avoid glitches + // propagating when changing aux mux. Note it would be a really bad idea + // to do this on one of the glitchless clocks (clk_sys, clk_ref). + else { + // Disable clock. On clk_ref and clk_sys this does nothing, + // all other clocks have the ENABLE bit in the same position. + hw_clear_bits(&clock->ctrl, CLOCKS_CLK_GPOUT0_CTRL_ENABLE_BITS); + } + + // Set aux mux first, and then glitchless mux if this clock has one + hw_write_masked(&clock->ctrl, + (auxsrc << CLOCKS_CLK_SYS_CTRL_AUXSRC_LSB), + CLOCKS_CLK_SYS_CTRL_AUXSRC_BITS + ); + + if (has_glitchless_mux(clk_index)) { + hw_write_masked(&clock->ctrl, + src << CLOCKS_CLK_REF_CTRL_SRC_LSB, + CLOCKS_CLK_REF_CTRL_SRC_BITS + ); + while (!(clock->selected & (1u << src))) + tight_loop_contents(); + } + + // Enable clock. On clk_ref and clk_sys this does nothing, + // all other clocks have the ENABLE bit in the same position. + hw_set_bits(&clock->ctrl, CLOCKS_CLK_GPOUT0_CTRL_ENABLE_BITS); + + // Now that the source is configured, we can trust that the user-supplied + // divisor is a safe value. + clock->div = div; + + // Store the configured frequency + //configured_freq[clk_index] = (uint32_t)(((uint64_t) src_freq << 8) / div); + + return true; +} +/// \end::clock_configure[] + +void __wrap_clocks_init(void) { + // Start tick in watchdog + watchdog_start_tick(XOSC_MHZ); + + // Disable resus that may be enabled from previous software + clocks_hw->resus.ctrl = 0; + + // Enable the xosc + xosc_init(); + + // Before we touch PLLs, switch sys and ref cleanly away from their aux sources. + hw_clear_bits(&clocks_hw->clk[clk_sys].ctrl, CLOCKS_CLK_SYS_CTRL_SRC_BITS); + while (clocks_hw->clk[clk_sys].selected != 0x1) + tight_loop_contents(); + hw_clear_bits(&clocks_hw->clk[clk_ref].ctrl, CLOCKS_CLK_REF_CTRL_SRC_BITS); + while (clocks_hw->clk[clk_ref].selected != 0x1) + tight_loop_contents(); + + /// \tag::pll_settings[] + // Configure PLLs + // REF FBDIV VCO POSTDIV + // PLL SYS: 12 / 1 = 12MHz * 125 = 1500MHz / 6 / 2 = 125MHz + // PLL USB: 12 / 1 = 12MHz * 100 = 1200MHz / 5 / 5 = 48MHz + /// \end::pll_settings[] + + /// \tag::pll_init[] + pll_init(pll_sys, 1, 1500 * MHZ, 6, 2); + pll_init(pll_usb, 1, 1200 * MHZ, 5, 5); + /// \end::pll_init[] + + // Configure clocks + // CLK_REF = XOSC (12MHz) / 1 = 12MHz + _clock_configure(clk_ref, + CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC, + 0, // No aux mux + 12 * MHZ, + 12 * MHZ, + 1 << 8); + + /// \tag::configure_clk_sys[] + // CLK SYS = PLL SYS (125MHz) / 1 = 125MHz + _clock_configure(clk_sys, + CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX, + CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS, + 125 * MHZ, + 125 * MHZ, + 1 << 8); + /// \end::configure_clk_sys[] + + // CLK USB = PLL USB (48MHz) / 1 = 48MHz + _clock_configure(clk_usb, + 0, // No GLMUX + CLOCKS_CLK_USB_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB, + 48 * MHZ, + 48 * MHZ, + 1 << 8); + + // CLK ADC = PLL USB (48MHZ) / 1 = 48MHz + _clock_configure(clk_adc, + 0, // No GLMUX + CLOCKS_CLK_ADC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB, + 48 * MHZ, + 48 * MHZ, + 1 << 8); + + // CLK RTC = PLL USB (48MHz) / 1024 = 46875Hz + _clock_configure(clk_rtc, + 0, // No GLMUX + CLOCKS_CLK_RTC_CTRL_AUXSRC_VALUE_CLKSRC_PLL_USB, + 48 * MHZ, + 46875, + 32 << 8); + + // CLK PERI = clk_sys. Used as reference clock for Peripherals. No dividers so just select and enable + // Normally choose clk_sys or clk_usb + _clock_configure(clk_peri, + 0, + CLOCKS_CLK_PERI_CTRL_AUXSRC_VALUE_CLK_SYS, + 125 * MHZ, + 125 * MHZ, + 1 << 8); +} diff --git a/ota/ota_command.h b/ota/ota_command.h new file mode 100644 index 00000000..e0b4d158 --- /dev/null +++ b/ota/ota_command.h @@ -0,0 +1,50 @@ +/* + ota_command.h - OTA stub that copies from LittleFS to flash + Copyright (c) 2022 Earle F. Philhower, III. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include + +#define _OTA_WRITE 1 +#define _OTA_VERIFY 1 + +typedef struct { + uint32_t command; + union { + struct { + char filename[64]; + uint32_t fileOffset; + uint32_t fileLength; + uint32_t flashAddress; // Normally XIP_BASE + } write; + }; +} commandEntry; + +// Must fit within 4K page +typedef struct { + uint8_t sign[8]; // "Pico OTA" + + // List of operations + uint32_t count; + commandEntry cmd[8]; + + uint32_t crc32; // CRC32 over just the contents of this struct, up until just before this value +} OTACmdPage; + +#define _OTA_COMMAND_FILE "otacommand.bin" diff --git a/ota/ota_lfs.c b/ota/ota_lfs.c new file mode 100644 index 00000000..db0cf5f6 --- /dev/null +++ b/ota/ota_lfs.c @@ -0,0 +1,196 @@ +/* + ota_lfs.c - LittleFS+GZIP support for OTA operations + Copyright (c) 2022 Earle F. Philhower, III. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "ota_lfs.h" +#include "ota_command.h" +#include "hardware/sync.h" +#include "hardware/flash.h" + +#include "../libraries/LittleFS/lib/littlefs/lfs.h" +#include "../libraries/LittleFS/lib/littlefs/lfs_util.h" +#include "./uzlib/src/uzlib.h" + +static lfs_t _lfs; +static struct lfs_config _lfs_cfg; + +static uint8_t *_start; +static uint32_t _blockSize; +static uint32_t _size; + +// The actual flash accessing routines +static lfs_block_t _lastBlock; +static int lfs_flash_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *dst, lfs_size_t size) { + (void) c; + memcpy(dst, _start + (block * _blockSize) + off, size); + _lastBlock = block; + return 0; +} + +static int lfs_flash_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { + (void) c; + uint8_t *addr = _start + (block * _blockSize) + off; + int save = save_and_disable_interrupts(); + flash_range_program((intptr_t)addr - (intptr_t)XIP_BASE, (const uint8_t *)buffer, size); + restore_interrupts(save); + return 0; +} + +static int lfs_flash_erase(const struct lfs_config *c, lfs_block_t block) { + (void) c; + uint8_t *addr = _start + (block * _blockSize); + int save = save_and_disable_interrupts(); + flash_range_erase((intptr_t)addr - (intptr_t)XIP_BASE, _blockSize); + restore_interrupts(save); + return 0; +} + +void lfsEraseBlock(uint32_t blockToErase) { + lfs_flash_erase(&_lfs_cfg, blockToErase); +} + +static int lfs_flash_sync(const struct lfs_config *c) { + /* NOOP */ + (void) c; + return 0; +} + +uint8_t _read_buffer[256]; +uint8_t _prog_buffer[256]; +uint8_t _lookahead_buffer[256]; +bool lfsMount(uint8_t *start, uint32_t blockSize, uint32_t size) { + _start = start; + _blockSize = blockSize; + _size = size; + + memset(&_lfs, 0, sizeof(_lfs)); + memset(&_lfs_cfg, 0, sizeof(_lfs_cfg)); + _lfs_cfg.context = NULL; + _lfs_cfg.read = lfs_flash_read; + _lfs_cfg.prog = lfs_flash_prog; + _lfs_cfg.erase = lfs_flash_erase; + _lfs_cfg.sync = lfs_flash_sync; + _lfs_cfg.read_size = 256; + _lfs_cfg.prog_size = 256; + _lfs_cfg.block_size = _blockSize; + _lfs_cfg.block_count = _blockSize ? _size / _blockSize : 0; + _lfs_cfg.block_cycles = 16; // TODO - need better explanation + _lfs_cfg.cache_size = 256; + _lfs_cfg.lookahead_size = 256; + _lfs_cfg.read_buffer = _read_buffer; + _lfs_cfg.prog_buffer = _prog_buffer; + _lfs_cfg.lookahead_buffer = _lookahead_buffer; + _lfs_cfg.name_max = 0; + _lfs_cfg.file_max = 0; + _lfs_cfg.attr_max = 0; + return lfs_mount(&_lfs, &_lfs_cfg) < 0 ? false : true; +} + +static bool _gzip = false; +static lfs_file_t _file; + +static unsigned char __attribute__((aligned(4))) uzlib_read_buff[4096]; +static unsigned char gzip_dict[32768]; +static uint8_t _flash_buff[4096]; // no room for this on the stack +static struct uzlib_uncomp m_uncomp; + +static uint8_t _ota_buff[256]; +static struct lfs_file_config _ota_cfg = { (void *)_ota_buff, NULL, 0 }; + +static uint8_t _file_buff[256]; +static struct lfs_file_config _file_cfg = { (void *)_file_buff, NULL, 0 }; + +bool lfsReadOTA(OTACmdPage *ota, uint32_t *blockToErase) { + lfs_file_t f; + + if (lfs_file_opencfg(&_lfs, &f, _OTA_COMMAND_FILE, LFS_O_RDONLY, &_ota_cfg) < 0) { + return false; + } + if (sizeof(*ota) != lfs_file_read(&_lfs, &f, ota, sizeof(*ota))) { + return false; + } + *blockToErase = _lastBlock; + // No need to close the file, it's open read-only and we're just going to reboot anyway + //lfs_file_close(&_lfs, &f); + return true; +} + +static int uzlib_read_cb(struct uzlib_uncomp *m) { + m->source = uzlib_read_buff; + int len = lfs_file_read(&_lfs, &_file, uzlib_read_buff, sizeof(uzlib_read_buff)); + m->source_limit = uzlib_read_buff + len; + return *(m->source++); +} + +bool lfsOpen(const char *filename) { + _gzip = false; + if (lfs_file_opencfg(&_lfs, &_file, filename, LFS_O_RDONLY, &_file_cfg) < 0) { + return false; + } + char b[2]; + if (sizeof(b) != lfs_file_read(&_lfs, &_file, b, sizeof(b))) { + return false; + } + lfs_file_rewind(&_lfs, &_file); + if ((b[0] == 0x1f) && (b[1] == 0x8b)) { + uzlib_init(); + m_uncomp.source = NULL; + m_uncomp.source_limit = NULL; + m_uncomp.source_read_cb = uzlib_read_cb; + uzlib_uncompress_init(&m_uncomp, gzip_dict, sizeof(gzip_dict)); + int res = uzlib_gzip_parse_header(&m_uncomp); + if (res != TINF_OK) { + lfs_file_rewind(&_lfs, &_file); + return false; // Error uncompress header read, could have been false alarm + } + _gzip = true; + + } + return true; +} + +bool lfsSeek(uint32_t offset) { + while (offset) { + uint32_t to_read = (offset > sizeof(_flash_buff)) ? sizeof(_flash_buff) : offset; + if (!lfsRead(to_read)) { + return false; + } + offset -= to_read; + } + return true; +} + +uint8_t *lfsRead(uint32_t len) { + if (!_gzip) { + int ret = lfs_file_read(&_lfs, &_file, _flash_buff, len); + return (len == ret) ? _flash_buff : NULL; + } + m_uncomp.dest_start = _flash_buff; + m_uncomp.dest = _flash_buff; + m_uncomp.dest_limit = _flash_buff + len; + int res = uzlib_uncompress(&m_uncomp); + if ((res != TINF_DONE) && (res != TINF_OK)) { + return NULL; + } + return _flash_buff; +} + +void lfsClose() { + // No need to close the file, it's open read-only and we're just going to reboot anyway + //lfs_file_close(&_lfs, &_file); +} diff --git a/ota/ota_lfs.h b/ota/ota_lfs.h new file mode 100644 index 00000000..08dde592 --- /dev/null +++ b/ota/ota_lfs.h @@ -0,0 +1,33 @@ +/* + ota_lfs.h - LittleFS+GZIP support for OTA operations + Copyright (c) 2022 Earle F. Philhower, III. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#pragma once + +#include +#include +#include "ota_command.h" + +bool lfsMount(uint8_t *start, uint32_t blockSize, uint32_t size); +bool lfsOpen(const char *filename); +bool lfsSeek(uint32_t offset); +uint8_t *lfsRead(uint32_t len); +void lfsClose(); + +bool lfsReadOTA(OTACmdPage *ota, uint32_t *blockToErase); +void lfsEraseBlock(uint32_t blockToErase); diff --git a/ota/pico_sdk_import.cmake b/ota/pico_sdk_import.cmake new file mode 100644 index 00000000..28efe9ea --- /dev/null +++ b/ota/pico_sdk_import.cmake @@ -0,0 +1,62 @@ +# This is a copy of /external/pico_sdk_import.cmake + +# This can be dropped into an external project to help locate this SDK +# It should be include()ed prior to project() + +if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH)) + set(PICO_SDK_PATH $ENV{PICO_SDK_PATH}) + message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT)) + set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT}) + message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')") +endif () + +if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH)) + set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH}) + message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')") +endif () + +set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK") +set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable") +set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK") + +if (NOT PICO_SDK_PATH) + if (PICO_SDK_FETCH_FROM_GIT) + include(FetchContent) + set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR}) + if (PICO_SDK_FETCH_FROM_GIT_PATH) + get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}") + endif () + FetchContent_Declare( + pico_sdk + GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk + GIT_TAG master + ) + if (NOT pico_sdk) + message("Downloading Raspberry Pi Pico SDK") + FetchContent_Populate(pico_sdk) + set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR}) + endif () + set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE}) + else () + message(FATAL_ERROR + "SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git." + ) + endif () +endif () + +get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}") +if (NOT EXISTS ${PICO_SDK_PATH}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found") +endif () + +set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake) +if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE}) + message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK") +endif () + +set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE) + +include(${PICO_SDK_INIT_CMAKE_FILE}) diff --git a/ota/uzlib b/ota/uzlib new file mode 160000 index 00000000..6d60d651 --- /dev/null +++ b/ota/uzlib @@ -0,0 +1 @@ +Subproject commit 6d60d651a4499a64f2e5b21b4cc08d98cb84b5c1 diff --git a/package/build_boards_manager_package.sh b/package/build_boards_manager_package.sh index 96e0d4eb..cb3d00d4 100755 --- a/package/build_boards_manager_package.sh +++ b/package/build_boards_manager_package.sh @@ -108,6 +108,8 @@ cat $srcdir/platform.txt | \ sed 's/^runtime.tools.pqt-.*.path=.*//g' | \ sed 's/^tools.uf2conv.cmd=.*//g' | \ sed 's/^#tools.uf2conv.cmd=/tools.uf2conv.cmd=/g' | \ +sed 's/^tools.uf2conv.network_cmd=.*//g' | \ +sed 's/^#tools.uf2conv.network_cmd=/tools.uf2conv.network_cmd=/g' | \ sed 's/^tools.picoprobe.cmd=.*//g' | \ sed 's/^#tools.picoprobe.cmd=/tools.picoprobe.cmd=/g' | \ sed 's/^tools.picodebug.cmd=.*//g' | \ diff --git a/platform.txt b/platform.txt index b1d2e714..11f8d107 100644 --- a/platform.txt +++ b/platform.txt @@ -42,7 +42,7 @@ compiler.warning_flags.more=-Wall -Werror=return-type -Wno-ignored-qualifiers compiler.warning_flags.all=-Wall -Wextra -Werror=return-type -Wno-ignored-qualifiers compiler.netdefines=-DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND=1 -DCYW43_LWIP=0 {build.lwipdefs} -DLWIP_IGMP=1 -DLWIP_CHECKSUM_CTRL_PER_NETIF=1 -compiler.defines={build.led} {build.usbstack_flags} -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {compiler.netdefines} +compiler.defines={build.led} {build.usbstack_flags} -DCFG_TUSB_MCU=OPT_MCU_RP2040 -DUSB_VID={build.vid} -DUSB_PID={build.pid} '-DUSB_MANUFACTURER={build.usb_manufacturer}' '-DUSB_PRODUCT={build.usb_product}' {compiler.netdefines} -DARDUINO_VARIANT="{build.variant}" compiler.includes="-iprefix{runtime.platform.path}/" "@{runtime.platform.path}/lib/platform_inc.txt" "-I{runtime.platform.path}/include" compiler.flags=-march=armv6-m -mcpu=cortex-m0plus -mthumb -ffunction-sections -fdata-sections {build.flags.exceptions} {build.flags.stackprotect} {build.flags.cmsis} compiler.wrap="@{runtime.platform.path}/lib/platform_wrap.txt" @@ -103,6 +103,9 @@ discovery.rp2040.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime # Compile patterns # ---------------- +## Generate signing header +recipe.hooks.sketch.prebuild.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime.platform.path}/tools/signing.py" --mode header --publickey "{build.source.path}/public.key" --out "{build.path}/core/Updater_Signing.h" + ## Compile c files recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} {build.usbpid} {build.usbpwr} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DBOARD_NAME="{build.board}" -DARDUINO_ARCH_{build.arch} {compiler.c.extra_flags} {build.extra_flags} {build.debug_port} {build.debug_level} {build.flags.optimize} {includes} "{source_file}" -o "{object_file}" @@ -124,11 +127,16 @@ recipe.hooks.linking.prelink.1.pattern="{runtime.tools.pqt-python3.path}/python3 recipe.hooks.linking.prelink.2.pattern="{compiler.path}{compiler.S.cmd}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} -c "{runtime.platform.path}/boot2/{build.boot2}.S" "-I{runtime.platform.path}/pico-sdk/src/rp2040/hardware_regs/include/" "-I{runtime.platform.path}/pico-sdk/src/common/pico_binary_info/include" -o "{build.path}/boot2.o" ## Combine gc-sections, archives, and objects -recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {compiler.ldflags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" "{build.path}/boot2.o" {compiler.libraries.ldflags} "{runtime.platform.path}/lib/{build.libpico}" {compiler.libbearssl} -lm -lc {build.flags.libstdcpp} -lc -Wl,--end-group +recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" "-L{build.path}" {compiler.c.elf.flags} {compiler.c.elf.extra_flags} {compiler.ldflags} "-Wl,--script={build.path}/memmap_default.ld" "-Wl,-Map,{build.path}/{build.project_name}.map" -o "{build.path}/{build.project_name}.elf" -Wl,--start-group {object_files} "{build.path}/{archive_file}" "{build.path}/boot2.o" "{runtime.platform.path}/lib/ota.o" {compiler.libraries.ldflags} "{runtime.platform.path}/lib/{build.libpico}" {compiler.libbearssl} -lm -lc {build.flags.libstdcpp} -lc -Wl,--end-group ## Create output (UF2 file) recipe.objcopy.uf2.pattern="{runtime.tools.pqt-elf2uf2.path}/elf2uf2" "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.uf2" +## Create output BIN (for OTA) +recipe.objcopy.bin.1.pattern="{compiler.path}/{compiler.objcopy.cmd}" -Obinary "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" +recipe.objcopy.bin.2.pattern="{runtime.tools.pqt-python3.path}/python3" -I "{runtime.platform.path}/tools/signing.py" --mode sign --privatekey "{build.source.path}/private.key" --bin "{build.path}/{build.project_name}.bin" --out "{build.path}/{build.project_name}.bin.signed" + + build.preferred_out_format=uf2 ## Save hex @@ -145,11 +153,14 @@ tools.uf2conv.path= # will point to "{runtime.platform.path}/tools/python3/python3" in GIT and # "{runtime.tools.pqt-python3.path}/python3" for JSON board manager releases. #tools.uf2conv.cmd={runtime.tools.pqt-python3.path}/python3 +#tools.uf2conv.network_cmd={runtime.tools.pqt-python3.path}/python3 tools.uf2conv.cmd={runtime.platform.path}/system/python3/python3 +tools.uf2conv.network_cmd={runtime.platform.path}/system/python3/python3 tools.uf2conv.upload.protocol=uf2 tools.uf2conv.upload.params.verbose= tools.uf2conv.upload.params.quiet= tools.uf2conv.upload.pattern="{cmd}" -I "{runtime.platform.path}/tools/uf2conv.py" --serial "{serial.port}" --family RP2040 --deploy "{build.path}/{build.project_name}.uf2" +tools.uf2conv.upload.network_pattern="{network_cmd}" -I "{runtime.platform.path}/tools/espota.py" -i "{serial.port}" -p "{network.port}" "--auth={network.password}" -f "{build.path}/{build.project_name}.bin" #tools.picoprobe.cmd={runtime.tools.pqt-openocd.path} tools.picoprobe.cmd={runtime.platform.path}/system/openocd diff --git a/tests/restyle.sh b/tests/restyle.sh index 2824f71c..aae714d5 100755 --- a/tests/restyle.sh +++ b/tests/restyle.sh @@ -4,7 +4,11 @@ for dir in ./cores/rp2040 ./libraries/EEPROM ./libraries/I2S \ ./libraries/LittleFS/src ./libraries/LittleFS/examples \ ./libraries/rp2040 ./libraries/SD ./libraries/ESP8266SdFat \ ./libraries/Servo ./libraries/SPI ./libraries/Wire \ - ./libraries/WiFi ./libraries/lwIP_Ethernet ./libraries/lwIP_CYW43; do + ./libraries/WiFi ./libraries/lwIP_Ethernet ./libraries/lwIP_CYW43 \ + ./libraries/FreeRTOS/src ./libraries/LEAmDNS ./libraries/MD5Builder \ + ./libraries/PicoOTA ./libraries/SDFS ./libraries/ArduinoOTA \ + ./libraries/Updater; do find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" \) -a \! -path '*api*' -exec astyle --suffix=none --options=./tests/astyle_core.conf \{\} \; find $dir -type f -name "*.ino" -exec astyle --suffix=none --options=./tests/astyle_examples.conf \{\} \; done + diff --git a/tools/build.py b/tools/build.py index b8bd53a0..86cc160b 100755 --- a/tools/build.py +++ b/tools/build.py @@ -67,6 +67,8 @@ def compile(tmp_dir, sketch, cache, tools_dir, hardware_dir, ide_path, f, args): 'usbstack={usbstack}'.format(**vars(args)) if "/WiFi" in sketch: fqbn = fqbn.replace("rpipico", "rpipicow") + if "/ArduinoOTA" in sketch: + fqbn = fqbn.replace("rpipico", "rpipicow") cmd += [fqbn] cmd += ['-built-in-libraries', ide_path + '/libraries'] cmd += ['-ide-version=10607'] diff --git a/tools/espota.py b/tools/espota.py new file mode 100755 index 00000000..de6ac082 --- /dev/null +++ b/tools/espota.py @@ -0,0 +1,345 @@ +#!/usr/bin/env python3 +# +# Original espota.py by Ivan Grokhotkov: +# https://gist.github.com/igrr/d35ab8446922179dc58c +# +# Modified since 2015-09-18 from Pascal Gollor (https://github.com/pgollor) +# Modified since 2015-11-09 from Hristo Gochkov (https://github.com/me-no-dev) +# Modified since 2016-01-03 from Matthew O'Gorman (https://githumb.com/mogorman) +# +# This script will push an OTA update to the ESP +# use it like: python3 espota.py -i -I -p -P [-a password] -f +# Or to upload SPIFFS image: +# python3 espota.py -i -I -p -P [-a password] -s -f +# +# Changes +# 2015-09-18: +# - Add option parser. +# - Add logging. +# - Send command to controller to differ between flashing and transmitting SPIFFS image. +# +# Changes +# 2015-11-09: +# - Added digest authentication +# - Enhanced error tracking and reporting +# +# Changes +# 2016-01-03: +# - Added more options to parser. +# + +from __future__ import print_function +import socket +import sys +import os +import optparse +import logging +import hashlib +import random + +# Commands +FLASH = 0 +SPIFFS = 100 +AUTH = 200 +PROGRESS = False +# update_progress() : Displays or updates a console progress bar +## Accepts a float between 0 and 1. Any int will be converted to a float. +## A value under 0 represents a 'halt'. +## A value at 1 or bigger represents 100% +def update_progress(progress): + if (PROGRESS): + barLength = 60 # Modify this to change the length of the progress bar + status = "" + if isinstance(progress, int): + progress = float(progress) + if not isinstance(progress, float): + progress = 0 + status = "error: progress var must be float\r\n" + if progress < 0: + progress = 0 + status = "Halt...\r\n" + if progress >= 1: + progress = 1 + status = "Done...\r\n" + block = int(round(barLength*progress)) + text = "\rUploading: [{0}] {1}% {2}".format( "="*block + " "*(barLength-block), int(progress*100), status) + sys.stderr.write(text) + sys.stderr.flush() + else: + sys.stderr.write('.') + sys.stderr.flush() + +def serve(remoteAddr, localAddr, remotePort, localPort, password, filename, command = FLASH): + # Create a TCP/IP socket + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + server_address = (localAddr, localPort) + logging.info('Starting on %s:%s', str(server_address[0]), str(server_address[1])) + try: + sock.bind(server_address) + sock.listen(1) + except Exception: + logging.error("Listen Failed") + return 1 + + # Check whether Signed Update is used. + if ( os.path.isfile(filename + '.signed') ): + filename = filename + '.signed' + file_check_msg = 'Detected Signed Update. %s will be uploaded instead.' % (filename) + sys.stderr.write(file_check_msg + '\n') + sys.stderr.flush() + logging.info(file_check_msg) + + content_size = os.path.getsize(filename) + f = open(filename,'rb') + file_md5 = hashlib.md5(f.read()).hexdigest() + f.close() + logging.info('Upload size: %d', content_size) + message = '%d %d %d %s\n' % (command, localPort, content_size, file_md5) + + # Wait for a connection + logging.info('Sending invitation to: %s', remoteAddr) + sock2 = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + remote_address = (remoteAddr, int(remotePort)) + sock2.sendto(message.encode(), remote_address) + sock2.settimeout(10) + try: + data = sock2.recv(128).decode() + except Exception: + logging.error('No Answer') + sock2.close() + return 1 + if (data != "OK"): + if(data.startswith('AUTH')): + nonce = data.split()[1] + cnonce_text = '%s%u%s%s' % (filename, content_size, file_md5, remoteAddr) + cnonce = hashlib.md5(cnonce_text.encode()).hexdigest() + passmd5 = hashlib.md5(password.encode()).hexdigest() + result_text = '%s:%s:%s' % (passmd5 ,nonce, cnonce) + result = hashlib.md5(result_text.encode()).hexdigest() + sys.stderr.write('Authenticating...') + sys.stderr.flush() + message = '%d %s %s\n' % (AUTH, cnonce, result) + sock2.sendto(message.encode(), remote_address) + sock2.settimeout(10) + try: + data = sock2.recv(32).decode() + except Exception: + sys.stderr.write('FAIL\n') + logging.error('No Answer to our Authentication') + sock2.close() + return 1 + if (data != "OK"): + sys.stderr.write('FAIL\n') + logging.error('%s', data) + sock2.close() + sys.exit(1) + return 1 + sys.stderr.write('OK\n') + else: + logging.error('Bad Answer: %s', data) + sock2.close() + return 1 + sock2.close() + + logging.info('Waiting for device...') + try: + sock.settimeout(10) + connection, client_address = sock.accept() + sock.settimeout(None) + connection.settimeout(None) + except Exception: + logging.error('No response from device') + sock.close() + return 1 + + received_ok = False + + try: + f = open(filename, "rb") + if (PROGRESS): + update_progress(0) + else: + sys.stderr.write('Uploading') + sys.stderr.flush() + offset = 0 + while True: + chunk = f.read(1460) + if not chunk: break + offset += len(chunk) + update_progress(offset/float(content_size)) + connection.settimeout(10) + try: + connection.sendall(chunk) + if connection.recv(32).decode().find('O') >= 0: + # connection will receive only digits or 'OK' + received_ok = True + except Exception: + sys.stderr.write('\n') + logging.error('Error Uploading') + connection.close() + f.close() + sock.close() + return 1 + + sys.stderr.write('\n') + logging.info('Waiting for result...') + # libraries/ArduinoOTA/ArduinoOTA.cpp L311 L320 + # only sends digits or 'OK'. We must not not close + # the connection before receiving the 'O' of 'OK' + try: + connection.settimeout(60) + received_ok = False + received_error = False + while not (received_ok or received_error): + reply = connection.recv(64).decode() + # Look for either the "E" in ERROR or the "O" in OK response + # Check for "E" first, since both strings contain "O" + if reply.find('E') >= 0: + sys.stderr.write('\n') + logging.error('%s', reply) + received_error = True + elif reply.find('O') >= 0: + logging.info('Result: OK') + received_ok = True + connection.close() + f.close() + sock.close() + if received_ok: + sys.stderr.write("Complete\n") + sys.stderr.flush() + return 0 + return 1 + except Exception: + logging.error('No Result!') + connection.close() + f.close() + sock.close() + return 1 + + finally: + connection.close() + f.close() + + sock.close() + return 1 +# end serve + + +def parser(unparsed_args): + parser = optparse.OptionParser( + usage = "%prog [options]", + description = "Transmit image over the air to the esp8266 module with OTA support." + ) + + # destination ip and port + group = optparse.OptionGroup(parser, "Destination") + group.add_option("-i", "--ip", + dest = "esp_ip", + action = "store", + help = "ESP8266 IP Address.", + default = False + ) + group.add_option("-I", "--host_ip", + dest = "host_ip", + action = "store", + help = "Host IP Address.", + default = "0.0.0.0" + ) + group.add_option("-p", "--port", + dest = "esp_port", + type = "int", + help = "ESP8266 ota Port. Default 8266", + default = 8266 + ) + group.add_option("-P", "--host_port", + dest = "host_port", + type = "int", + help = "Host server ota Port. Default random 10000-60000", + default = random.randint(10000,60000) + ) + parser.add_option_group(group) + + # auth + group = optparse.OptionGroup(parser, "Authentication") + group.add_option("-a", "--auth", + dest = "auth", + help = "Set authentication password.", + action = "store", + default = "" + ) + parser.add_option_group(group) + + # image + group = optparse.OptionGroup(parser, "Image") + group.add_option("-f", "--file", + dest = "image", + help = "Image file.", + metavar="FILE", + default = None + ) + group.add_option("-s", "--spiffs", + dest = "spiffs", + action = "store_true", + help = "Use this option to transmit a SPIFFS image and do not flash the module.", + default = False + ) + parser.add_option_group(group) + + # output group + group = optparse.OptionGroup(parser, "Output") + group.add_option("-d", "--debug", + dest = "debug", + help = "Show debug output. And override loglevel with debug.", + action = "store_true", + default = False + ) + group.add_option("-r", "--progress", + dest = "progress", + help = "Show progress output. Does not work for ArduinoIDE", + action = "store_true", + default = False + ) + parser.add_option_group(group) + + (options, args) = parser.parse_args(unparsed_args) + + return options +# end parser + + +def main(args): + # get options + options = parser(args) + + # adapt log level + loglevel = logging.WARNING + if (options.debug): + loglevel = logging.DEBUG + # end if + + # logging + logging.basicConfig(level = loglevel, format = '%(asctime)-8s [%(levelname)s]: %(message)s', datefmt = '%H:%M:%S') + + logging.debug("Options: %s", str(options)) + + # check options + global PROGRESS + PROGRESS = options.progress + if (not options.esp_ip or not options.image): + logging.critical("Not enough arguments.") + + return 1 + # end if + + command = FLASH + if (options.spiffs): + command = SPIFFS + # end if + + return serve(options.esp_ip, options.host_ip, options.esp_port, options.host_port, options.auth, options.image, command) +# end main + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) +# end if diff --git a/tools/platformio-build.py b/tools/platformio-build.py index aaf7e8cb..783134f7 100755 --- a/tools/platformio-build.py +++ b/tools/platformio-build.py @@ -300,6 +300,11 @@ if variant != "": os.path.join(FRAMEWORK_DIR, "variants", variant) ]) + env.Append(CPPDEFINES=[ + ("ARDUINO_VARIANT", '"' + variant + '"'), + ]) + + # link variant's source files as object files into the binary. # otherwise weak function overriding won't work in the linking stage. env.BuildSources( diff --git a/tools/signing.py b/tools/signing.py new file mode 100755 index 00000000..e4f3e11c --- /dev/null +++ b/tools/signing.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# +import argparse +import hashlib +import os +import subprocess +import sys + +def parse_args(): + parser = argparse.ArgumentParser(description='Binary signing tool') + parser.add_argument('-m', '--mode', help='Mode (header, sign)') + parser.add_argument('-b', '--bin', help='Unsigned binary') + parser.add_argument('-o', '--out', help='Output file'); + parser.add_argument('-p', '--publickey', help='Public key file'); + parser.add_argument('-s', '--privatekey', help='Private(secret) key file'); + return parser.parse_args() + +def sign_and_write(data, priv_key, out_file): + """Signs the data (bytes) with the private key (file path).""" + """Save the signed firmware to out_file (file path).""" + + signcmd = [ 'openssl', 'dgst', '-sha256', '-sign', priv_key ] + proc = subprocess.Popen(signcmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + signout, signerr = proc.communicate(input=data) + if proc.returncode: + sys.stderr.write("OpenSSL returned an error signing the binary: " + str(proc.returncode) + "\nSTDERR: " + str(signerr)) + else: + with open(out_file, "wb") as out: + out.write(data) + out.write(signout) + out.write(b'\x00\x01\x00\x00') + sys.stderr.write("Signed binary: " + out_file + "\n") + +def main(): + args = parse_args() + if args.mode == "header": + val = "" + try: + with open(args.publickey, "rb") as f: + pub = f.read() + val += "#include \n" + val += "#define ARDUINO_SIGNING 1\n" + val += "static const char signing_pubkey[] PROGMEM = {\n" + for i in bytearray(pub): + val += "0x%02x, \n" % i + val = val[:-3] + val +="\n};\n" + sys.stderr.write("Enabling binary signing\n") + except IOError: +# Silence the default case to avoid people thinking something is wrong. +# Only people who care about signing will know what it means, anyway, +# and they can check for the positive acknowledgement above. +# sys.stderr.write("Not enabling binary signing\n") + val += "#define ARDUINO_SIGNING 0\n" + outdir = os.path.dirname(args.out) + if not os.path.exists(outdir): + os.makedirs(outdir) + try: + with open(args.out, "r") as inp: + old_val = inp.read() + if old_val == val: + return + except Exception: + pass + with open(args.out, "w") as f: + f.write(val) + return 0 + elif args.mode == "sign": + if not os.path.isfile(args.privatekey): + return + try: + with open(args.bin, "rb") as b: + bin = b.read() + + sign_and_write(bin, args.privatekey, args.out) + + except Exception as e: + sys.stderr.write(str(e)) + sys.stderr.write("Not signing the generated binary\n") + return 0 + else: + sys.stderr.write("ERROR: Mode not specified as header or sign\n") + +if __name__ == '__main__': + sys.exit(main()) +